AngularJS 拦截器
在需要进行身份验证时,在请求发送给服务器之前或者从服务器返回时对其进行拦截,是比较好的实现手段。
例如,对于身份验证,如果服务器返回401状态码,将用户重定向到登录页面。
AngularJS通过拦截器提供了一个从全局层面对响应进行处理的途径。
拦截器是$http服务的基础中间件,用来向应用的业务流程中注入新的逻辑。
一共有四种拦截器,两种成功,两种失败。
request AngularJS通过$http设置对象来对请求拦截器进行调用。
response
requestError
responseError
通过两个步骤来使用拦截器:
在.factory()方法中创建拦截器,然后使用$httpProvider在.config()中注册拦截器:
angular.module("myApp", [])
.factory("myInterceptor", function($q) {
var interceptor = {}; return interceptor; }); //第一步
angular.module("myApp", [])
.config( function($httpProvider) {
$httpProvider.interceptors.push("myInterceptor"); }); //第二步
设置$httpProvider
使用.config()可以向所有请求中添加特定的HTTP头,这对于我们身份验证的时候非常有用。默认的请求头保存在$httpProvider.defaults.headers.common对象中,默认形式如下
Accept: application/json, text/plain, */*
通过.config()函数可以对这些头进行修改或扩充
angular.module("myApp", [])
.config(function($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-By'] = "MyAngularApp"; });
也可以在运行时通过$http对象的defaults属性对这些默认值进行修改,例如
$http.defaults.common['X-Auth'] = "RandomString";
有时候只需要对post类型请求进行设置,默认的post请求头是
Content-Type: application/json
可以在.config()函数中对post请求的头进行修改或扩充
angular.module("myApp", [])
.config(function($httpProvider) { $httpProvider.defaults.headers.post['X-Posted-By'] = "MyAngularApp"; });
在一篇叫做《Interceptors in AngularJS and Useful Examples By Naor Yehudaey》的文章中有一个例子用以实现服务端的认证,这种方式叫做Token-Based验证,当用户登录的时候,会从后台拿到一个sessionToken,sessionToken在服务端标识了每个用户,并且会包含在发送服务端的每个请求中。
下面sessionInjector为每个被捕获的请求添加了x-session-token头(如果用户已经登录)
module.factory("sessionInjector", ["SessionService", function(SessionService) {
var sessionInjector = {request: function(config) {if( !SessionService.isAnonymus) { config.headers["x-session-token"] = SessionService.token; } return config; } }; return sessionInjector; }]);
module.config(["$httpProvider", function($httpProvider) { $httpProvider.interceptors.push("sessionInjector"); }]);
然后创建一个请求:
$http.get("url");
被sessionInjector拦截之前的配置对象是这样:
{ "transformRequest": [null],"transformResponse": [null], "method": "GET", "url": url, "headers": {"Accept": "application/json, text/plain, */*" } }
被sessionInjector拦截之后的配置对象是:
{"transformRequest": [null], "transformResponse": [null], "method": "GET", "url": url, "headers": {"Accept": "application/json, text/plain, */*", "x-session-token": 415954427904 } }