Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 你如何';拦截';EmberJs应用程序中的所有HTTP请求?_Javascript_Angularjs_Http_Ember.js_Interceptor - Fatal编程技术网

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

Javascript 你如何';拦截';EmberJs应用程序中的所有HTTP请求?,javascript,angularjs,http,ember.js,interceptor,Javascript,Angularjs,Http,Ember.js,Interceptor,我希望能够捕获所有HTTP请求和响应,并在它们进入EmberJs应用程序的其余部分之前对它们进行修改。我想在全球范围内——在整个应用程序中这样做。我一直没能找到这个。如何做到这一点 (修改是基于某些标头执行某些条件逻辑,或添加或修改某些标头) 在AngularJS中,您可以通过以下方式完成此任务: App.factory('AppHttpInterceptor', function($q) { return { request: function(req) {

我希望能够捕获所有HTTP请求和响应,并在它们进入EmberJs应用程序的其余部分之前对它们进行修改。我想在全球范围内——在整个应用程序中这样做。我一直没能找到这个。如何做到这一点

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


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

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

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

相反,使用Ember,您必须自己构建服务和服务提供商概念。您可以采用类似的方式,并以使用您描述的属性的方式对其进行扩展。此库提供了一个
Ember.resource
方法,您可以使用prototype从中进行扩展:

Ember.ResourceAdapter.extend({
    _prepareResourceRequest: function(params) {
      params.beforeSend = function (xhr, settings) {
       //set your xhr interceptors here
      }
    }
  });
编辑:澄清在ember中使用
$ajax
,在Angular中使用
$http
(承诺vs回调) angular使响应拦截器成为可能的最大区别在于angular中的异步请求是
承诺
,而
$ajax
调用则不是。在不太深入的情况下,您可以为承诺的每一步分配变量,使其在每一步都可以进行变异/处理,而使用
$ajax
,您只能在数据完全返回时执行操作。使用Promission,在Promission生命周期中的任何时间点分配变量以表示状态,并且使用该引用,您可以在Promission事件完全解决之前的任何时间点根据需要修改Promission

因此,为什么可以使用
$ajaxPrefilter
执行请求拦截器,但使用
$ajax
的抽象配置方法执行响应拦截器却没有好方法。为了在Ember中真正实现AngularJS对
$http
的功能,您需要创建一个基于承诺的异步请求/响应服务,而不是使用非基于承诺的xhr请求,如
$ajax

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

我发现一个关于这个主题的视频特别有启发性,它来自ng conf 2014:

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


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

问得好。想了一会儿,它被错误地标记为angularjs。谢谢你的回答。我认为,这意味着余烬并没有提供一种方法来自己做到这一点。由于Ember(目前)使用jQuery来处理其所有AJAX请求,我想为什么不研究一下,结果证明它提供了一种拦截所有HTTP请求的方法。还没有找到拦截响应的函数…没错。余烬本身并不是独立完成这项任务的。我本打算建议您使用jQuery找到的代码,但它不完全相同。angularjs使用Promissions,这使响应拦截器能够发生,而常规的old
$ajax
是一种基于回调的服务,只能过滤回调中的数据。我编辑了我的答案来解释差异。+1并向您核对。非常感谢您的透彻解释-我的印象是Ember使用包装其HTTP请求,但我一定是弄错了。再次更新我的答案以解决此问题。TL;DR,RSVP是一个promise类,但不是ajax请求服务。angular将两者结合起来,然后使用其他几个OO模式来允许您的问题和我的答案所描述的配置。