你如何"拦截"EmberJs应用程序中的所有HTTP请求?

bgu*_*uiz 5 javascript http interceptor ember.js angularjs

我希望能够捕获所有HTTP请求和响应,并在它们到达EmberJs应用程序的其余部分之前进行修改.我想在全球范围内这样做 - 在整个应用程序中.我无法通过API找到这种挖掘方式.如何才能做到这一点?

(修改是基于某些标头执行某些条件逻辑,或添加或修改某些标头).


在AngularJS中,您可以使用以下内容完成此操作:

App.factory('AppHttpInterceptor', function($q) {
    return {
        request: function(req) {
            //modify request
            return req;
        },
        response: function(res) {
            // modify response
            return res || $q.when(res);
        }
    };
});

App.config(function ($httpProvider) {
  $httpProvider.interceptors.push('AppHttpInterceptor');
});
Run Code Online (Sandbox Code Playgroud)

Bri*_*sch 7

首先,重要的是要注意Angular和Ember不是为了达到同样的目的而构建的.它们都是javascript框架,而这就是相似之处的结束.两个框架中异步请求差异的另一个重要因素是Angular将promises集成到它的异步服务中.Ember异步服务不是基于承诺的,因此无法使用响应拦截器(请参阅下面的注释).

AngularJS提供$httpProvider了一个可配置的单例,它返回一个配置的实例$http 作为promise对象.Angular专注于服务而不是方法(尽管它确实提供了一些方法),这就是Angular与其他框架(如Ember)的区别,它为您提供构建服务的结构,但不提供服务的核心.

相反,使用Ember,您必须自己构建服务和服务提供商概念.你可以采取类似cerebris/ember-rest之类的东西,并以使用你描述的属性的方式扩展它.这个库提供了一个Ember.resource方法,你可以使用原型从那里扩展:

Ember.ResourceAdapter.extend({
    _prepareResourceRequest: function(params) {
      params.beforeSend = function (xhr, settings) {
       //set your xhr interceptors here
      }
    }
  });
Run Code Online (Sandbox Code Playgroud)

编辑:澄清使用$ajaxember和$httpAngular(promises vs callbacks)

关于角度如何使响应拦截器成为可能的最大区别在于,角度中的异步请求是promises,而$ajax呼叫则不是.如果没有过多地进入杂草,您可以将变量分配给承诺的每个步骤,使其可用于沿着路径的每个步骤进行变异/处理,而使用时$ajax,您只能在数据完全返回时执行操作.使用Promises,在promise的生命周期中的任何时刻分配变量来表示状态,并使用该引用,您可以在promise完全解析之前的任何时间点根据需要变更promise.

因此,为什么可以使用抽象配置方法来执行请求拦截器,$ajaxPrefilter没有好的方法来执行响应拦截器$ajax.要在Ember中真正做到AngularJS所做的事情$http,您需要创建基于异步请求/响应服务的承诺,而不是使用非基于承诺的xhr请求,例如$ajax.

jQuery确实提供了一个$ajaxSetup()方法,您可以将该dataFilter属性设置为并定义处理函数,但不建议这样做.使用angular,$httpProvider可以通过模块进行配置,通过解耦和Separation of Concerns,这可以变得非常强大,允许您通过大量控制来封装和级联http拦截器配置.对ajax设置进行相同的更改将在全局jquery命名空间中注册,如果需要扩展应用程序,则可能会导致冲突.

我发现一个关于这个主题特别有启发性的视频来自ng-conf 2014:Christion Lilley:Going Postal with Angular Promises

编辑2:解决Ember.RSVP

虽然Ember.RSVP确实是框架中可用的promise类,但它没有任何可用于执行资源请求的方法.这意味着您必须手动将http请求实例分配给RSVP.deferred实例,以便在返回promise之前解析您的http请求.

这允许您在每个单独请求的两侧执行拦截器,但不提供为所有请求配置拦截器的解决方案.您必须为此创建另一个函数或服务,并使用此函数扩展RSVP.