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

时间:2014-02-23 23:28:45

标签: javascript angularjs http ember.js interceptor

我希望能够捕获所有HTTP请求和响应,并在它们到达EmberJs应用程序的其余部分之前进行修改。我想在全球范围内这样做 - 在整个应用程序中。我无法通过the 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');
});

1 个答案:

答案 0 :(得分:6)

首先,重要的是要注意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
      }
    }
  });

编辑:澄清使用ember中的$ajax和Angular中的$http(承诺与回调)

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

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

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

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

编辑2:解决Ember.RSVP

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

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