在 angularjs 拦截器中停止请求
Posted
技术标签:
【中文标题】在 angularjs 拦截器中停止请求【英文标题】:Stop request in angularjs interceptor 【发布时间】:2014-10-17 20:53:52 【问题描述】:如何在 Angularjs 拦截器中停止请求。
有没有办法做到这一点?
我尝试使用承诺并发送拒绝而不是解决!
.factory('connectionInterceptor', ['$q', '$timeout',
function($q, $timeout)
var connectionInterceptor =
request: function(config)
var q = $q.defer();
$timeout(function()
q.reject();
, 2000)
return q.promise;
// return config;
return connectionInterceptor;
])
.config(function($httpProvider)
$httpProvider.interceptors.push('connectionInterceptor');
);
【问题讨论】:
发布您尝试过的代码。否则,我们无法向您解释为什么它不起作用,以及如何解决它。 @JBNizet 添加了!请检查代码! 不确定为什么要等待 2 秒,但您的代码运行良好。没有发送 HTTP 请求。见plnkr.co/edit/x4YGC7l4B66RGTmWB7Ts?p=preview。打开您的开发工具,并检查您的网络选项卡:未发送对 README 的请求。现在注释掉拦截器的注册,做同样的测试,你会看到请求出去了,并显示成功警报。 好吧,请注意所有 ajax 请求都会通过您的拦截器,包括加载 html 模板的请求。如果这不是问题,请发布一个重现问题的 plunkr。 检查config.url
的值。
【参考方案1】:
我最终使用以下角度拦截器绕过了角度 XHR 调用:
function HttpSessionExpiredInterceptor(sessionService)
return
request: function(config)
if (sessionService.hasExpired())
/* Avoid any other XHR call. Trick angular into thinking it's a GET request.
* This way the caching mechanism can kick in and bypass the XHR call.
* We return an empty response because, at this point, we do not care about the
* behaviour of the app. */
if (_.startsWith(config.url, '/your-app-base-path/'))
config.method = 'GET';
config.cache =
get: function()
return null;
;
return config;
;
这样,任何请求,POST,PUT,...都被转换为 GET,这样缓存机制就可以 由角使用。此时,您可以使用自己的缓存机制,在我的情况下,当 session 过期了,我不再关心返回什么了。
【讨论】:
我知道这是一个旧答案,但这非常聪明。【参考方案2】:$http 服务有一个选项 超时来完成这项工作。 你可以这样做:
angular.module('myApp')
.factory('httpInterceptor', ['$q', '$location',function ($q, $location)
var canceller = $q.defer();
return
'request': function(config)
// promise that should abort the request when resolved.
config.timeout = canceller.promise;
return config;
,
'response': function(response)
return response;
,
'responseError': function(rejection)
if (rejection.status === 401)
canceller.resolve('Unauthorized');
$location.url('/user/signin');
if (rejection.status === 403)
canceller.resolve('Forbidden');
$location.url('/');
return $q.reject(rejection);
;
])
//Http Intercpetor to check auth failures for xhr requests
.config(['$httpProvider',function($httpProvider)
$httpProvider.interceptors.push('httpInterceptor');
]);
【讨论】:
【参考方案3】:不确定一般情况下是否可行。但是您可以使用“取消器”启动 $http 请求。
这是来自this answer的示例:
var canceler = $q.defer();
$http.get('/someUrl', timeout: canceler.promise).success(successCallback);
// later...
canceler.resolve(); // Aborts the $http request if it isn't finished.
因此,如果您可以控制启动请求的方式,这可能是一个选择。
【讨论】:
我想要一个使用拦截器的通用解决方案! @vipulsodha Whisher 的回答似乎是这个想法的一个很好的实现。【参考方案4】:我只是以空对象的形式返回
'request': function request(config)
if(shouldCancelThisRequest)
return ;
return config;
【讨论】:
【参考方案5】:这对我有用,特别是为了停止传出请求和模拟数据:
app
.factory("connectionInterceptor", [
"$q",
function ($q)
return
request: function (config)
// you can intercept a url here with (config.url == 'https://etc...') or regex or use other conditions
if ("conditions met")
config.method = "GET";
// this is simulating a cache object, or alternatively, you can use a real cache object and pre-register key-value pairs,
// you can then remove the if block above and rely on the cache (but your cache key has to be the exact url string with parameters)
config.cache =
get: function (key)
// because of how angularjs $http works, especially older versions, you need a wrapping array to get the data
// back properly to your methods (if your result data happens to be an array). Otherwise, if the result data is an object
// you can pass back that object here without any return codes, status, or headers.
return [200, mockDataResults, , "OK"];
,
;
return config;
,
;
,
])
.config(function ($httpProvider)
$httpProvider.interceptors.push("connectionInterceptor");
);
如果您试图模拟类似的结果
[42, 122, 466]
您需要返回一个带有一些 http 参数的数组,不幸的是,这正是 ng sendReq() 函数的编写方式。 (参见https://github.com/angular/angular.js/blob/e41f018959934bfbf982ba996cd654b1fce88d43/src/ng/http.js#L1414 的第 1414 行或下面的 sn-p)
// from AngularJS http.js
// serving from cache
if (isArray(cachedResp))
resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3], cachedResp[4]);
else
resolvePromise(cachedResp, 200, , 'OK', 'complete');
【讨论】:
以上是关于在 angularjs 拦截器中停止请求的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS 拦截器没有将 JWT Bearer 放入 node.js 应用程序的每个请求中