【问题标题】:How do you 'intercept' all HTTP requests in an EmberJs app?如何在 EmberJs 应用程序中“拦截”所有 HTTP 请求?
【发布时间】:2014-03-25 10:21:35
【问题描述】:

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

(修改是基于某些header执行一些条件逻辑,或者添加或修改某些headers)。


在 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');
});

【问题讨论】:

  • 好问题。想了一会儿它被错误地标记为angularjs。

标签: javascript angularjs http ember.js interceptor


【解决方案1】:

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

AngularJS 提供$httpProvider 作为一个可配置的单例,它返回一个配置好的$http 实例作为一个承诺对象。 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(承诺与回调)

Angular 如何使响应拦截器成为可能的最大区别在于,Angular 中的异步请求是 promises,而 $ajax 调用不是。无需过多关注,您可以为 Promise 的每个步骤分配变量,使其在每个步骤中都可用于突变/处理,而使用 $ajax,您只能在数据完全返回时执行操作.使用 Promises,在 Promise 的生命周期中的任何时间点分配变量来表示状态,并使用该引用,您可以在 Promise 完全解决之前的任何时间点根据需要更改 Promise。

这就是为什么可以用$ajaxPrefilter 做请求拦截器,但是没有没有很好的方法来做响应拦截器,使用$ajax 的抽象配置方法。要在 Ember 中真正做到 AngularJS 对 $http 所做的事情,您需要创建一个基于 Promise 的异步请求/响应服务,而不是使用基于非 Promise 的 xhr 请求,例如 $ajax

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

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

编辑 2:寻址 Ember.RSVP

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

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

【讨论】:

  • 感谢您的回答。我认为这意味着 Ember 不提供自行执行此操作的方法。由于 Ember(目前)使用 jQuery 来处理它的所有 AJAX 请求,我想为什么不研究一下,结果$.ajaxPrefilter 提供了一种拦截所有 HTTP 请求的方法。虽然还没有找到拦截响应的函数...
  • 没错。 Ember 本身不会自行执行此操作。我打算建议您使用 jQuery 找到的内容,但它并不完全相同。 angularjs 使用 Promise,它使响应拦截器发生,而常规的旧 $ajax 是基于回调的服务,并且只能在回调中过滤数据。我编辑了答案以解释差异。
  • +1 并检查给你。非常感谢您的详尽解释 - 我的印象是 Ember 使用 their RSVP promises 包装其 HTTP 请求,但我一定是弄错了。
  • 再次更新了我的答案以解决这个问题。 TL;DR,RSVP 是一个承诺类,但不是一个 ajax 请求服务。 angular 将两者结合起来,然后使用其他几种 OO 模式来允许您的问题和我的回答所描述的配置。
猜你喜欢
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
相关资源
最近更新 更多