你如何“拦截”在EmberJs应用所有的HTTP请求? [英] How do you 'intercept' all HTTP requests in an EmberJs app?

查看:358
本文介绍了你如何“拦截”在EmberJs应用所有的HTTP请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想能够捕获所有HTTP请求和响应,并修改他们,他们得到一个EmberJs应用程序的其余部分之前。我愿做这一全球 - 在整个应用程序。我一直没能找到通过的API 这挖。如何才能做到这一点?

(修改执行基于某些头文件中的一些条件逻辑,或者添加或修改某些头)。


在AngularJS,你可以做到这一点使用是这样的:

  App.factory('AppHttpInterceptor',函数($ Q){
    返回{
        要求:功能(REQ){
            //修改请求
            返回REQ;
        },
        回应:功能(RES){
            //修改响应
            返回水库|| $ q.when(RES);
        }
    };
});App.config中(函数($ httpProvider){
  $ httpProvider.interceptors.push('AppHttpInterceptor');
});


解决方案

首先,要注意角度和灰烬未建成达到同样的目的是很重要的。他们都是JavaScript框架,这是对的相似之处。在两个框架异步请求的差异的另一大因素是角度的整合承诺到它的异步服务。灰烬异步服务不答应为主,因此响应拦截器是不可能的(见下面我的注意)。

AngularJS提供了 $ httpProvider 作为配置单返回 $ HTTP 的配置实例的作为诺对象的。角侧重于服务,而不是方法(虽然它确实有一个的的方法,它给你),而这正是其他框架,如灰烬,这给你建立服务结构与众不同角,但没有按'T提供服务,它的核心。

相反,与Ember,你必须自己构建一个服务和服务供应商的概念。你可以采取类似 cerebris /余烬静止和它以这样的方式,以使用扩展你描述的属性。该库提供了一个 Ember.resource 方法,你可以使用原型从那里扩展:

  Ember.ResourceAdapter.extend({
    _ prepareResourceRequest:功能(PARAMS){
      params.beforeSend =功能(XHR,设置){
       //这里设置XHR拦截器
      }
    }
  });

编辑:在烬使用 $阿贾克斯澄清和 $ HTTP 在角(承诺VS回调)

如何角使得响应拦截可能的话,最大的区别是,在角异步请求承诺,而 $阿贾克斯电话都没有。没有得到太多的入杂草,你可以分配变量一个承诺的每一步,用 $阿贾克斯使其可用于突变/沿线的每一步操作,而,则只能执行操作时的数据已经完全恢复。有了承诺,分配变量在任何时候承诺的生命周期中重新present状态,并使用该引用,您可以根据需要及时完全解决的承诺的事件之前发生变异的承诺,在任何时候。

因此​​它为什么可以做到的请求拦截器与 $阿贾克斯prefilter 没有什么好办法做到响应拦截,使用与 $阿贾克斯抽象的配置方法。要真正做到在灰烬与 $ HTTP 呢,你需要什么AngularJS创建一个承诺基于异步请求/响应服务,而不是利用基于非承诺XHR请求,如 $阿贾克斯

jQuery也提供了一个 $ ajaxSetup()方法,你也许能在 dataFilter 属性设置为并定义处理函数,但不建议这样做。具有角,在 $ httpProvider 可以按模块进行配置,并通过去耦和关注点分离,这可以成为真正强大的,让你来封装和级联HTTP拦截配置有很多的控制。使你的AJAX设置相同的变化将注册自己在全球jQuery的命名空间,如果你需要增加你的应用程序可能会导致冲突。

一个视频中,我发现特别englightening对这个问题是从NG-conf的2014年: Christion李洁明:走向邮政与角承诺

编辑2:解决Ember.RSVP

Ember.RSVP 的确是一个承诺类可用的框架,它没有可用于执行资源请求的任何方法。这意味着你必须在一个HTTP请求实例手动分配到RSVP.deferred的实例,使得它解决在返回之前承诺的HTTP请求。

这允许你做的每个单独的请求两侧拦截器,但不提供配置拦截器为所有请求的解决方案。你不得不创造另一个功能或服务,使用此功能扩展的RSVP。

I would like to be able to capture all HTTP requests and responses, and modify them, before they get to the rest of an EmberJs app. I would like to do this globally - across the entire app. I have not been able to find this digging through the API. How can this be done?

(Modification is to perform some conditional logic based in certain headers, or to add or modify certain headers).


In AngularJS, you can accomplish this using something like this:

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

解决方案

First, it's important to note that Angular and Ember are not built to serve the same purpose. They are both javascript frameworks, and that's about where the similarities end. Another big factor in the difference of async requests in the two framework is Angular's integration of promises into it's async services. Ember async services are not promise based, and therefore response interceptors are not possible (see my note below).

AngularJS provides $httpProvider as a configurable singleton that returns a configured instance of $http as a promise object. Angular focuses on services rather than methods (although it does have a few methods it gives you), and that's what sets Angular apart from other frameworks like Ember, which give you a structure to build services, but doesn't provide services in it's core.

Instead, with Ember, you'd have to build a service and service provider concept yourself. You could take something like cerebris/ember-rest, and extend it in such a way as to use properties you describe. This library provides an Ember.resource method, which you could use prototype to extend from there:

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

Edit: Clarification on use of $ajax in ember and $http in Angular (promises vs callbacks)

The biggest difference on how angular makes response interceptors possible, is that async requests in angular are promises, whereas $ajax calls are not. Without getting too much into the weeds, you can assign variables to each step of a promise, making it available for mutation/handling along every step of the way, whereas with $ajax, you can only perform operations when the data has completely returned. With Promises, assign variables to represent states at any point during the lifecycle of the promise, and using that reference, you can mutate the promise as needed, at any point in time prior to the event of the promise fully resolving.

Thus why it's possible to do request interceptors with $ajaxPrefilter but there is no good way to do response interceptors, using the abstract configuration approach with $ajax. To truly do in Ember what AngularJS does with $http, you need to create a promise based async request/response service, as opposed to utilizing non-promise based xhr requests such as $ajax.

jQuery does provide an $ajaxSetup() method, which you might be able to set a dataFilter property to and define a handler function, however this is not recommended. With angular, the $httpProvider can be configured by module, and through de-coupling and Separation of Concerns, this can become truly powerful, allowing you to encapsulate and cascade http interceptor configurations with a lot of control. Making the same changes to your ajax settings will register themselves on the global jquery namespace, and can cause conflicts if you need to grow your app.

One video I found particularly englightening on this subject was from ng-conf 2014: Christion Lilley: Going Postal with Angular Promises

Edit 2: addressing Ember.RSVP

While Ember.RSVP is indeed a promise class useable in the framework, it does not have any methods available to perform resource requests. This means you have to manually assign an http request instance to an instance of RSVP.deferred such that it resolves your http request before returning the promise.

This allows you to do interceptors on both sides of each individual request, but does not provide a solution for configuring interceptors for all requests. You'd have to create another function or service for that, and extend RSVP with this function.

这篇关于你如何“拦截”在EmberJs应用所有的HTTP请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆