我想在我的应用程序中使用请求拦截器将验证代码添加到请求中(用于CSRF保护)。我的代码现在看起来像这样:
$httpProvider.interceptors.push(function($q, $injector, AppConst) {
return {
request: function(request) {
var VerifyCodeService = $injector.get('VerifyCodeService');
var verifyCodeUrl = AppConst.apiUrl + '/app/verifyCode'
if(request.url!=verifyCodeUrl && request.data!=undefined){
VerifyCodeService.getCode()
.then(function(data) {
if (AppConst.serviceResponseOk==data.result) {
request.data.verifyCode = data.verifyCode;
return request;
} else {
console.log('error');
return request;
}
}, function(error) {
console.log('error:' + error);
return request;
});
} else {
return request;
}
}
};
});
但由于某种原因,我不断收到此错误:
TypeError: Cannot read property 'headers' of undefined
at serverRequest (angular.js:10028)
at processQueue (angular.js:14567)
at angular.js:14583
at Scope.$eval (angular.js:15846)
at Scope.$digest (angular.js:15657)
at Scope.$apply (angular.js:15951)
at done (angular.js:10364)
at completeRequest (angular.js:10536)
at XMLHttpRequest.requestLoaded (angular.js:10477)
有谁知道发生了什么事?
答案 0 :(得分:1)
如果我读得正确,你正在制作一个XHR,它会触发另一个XHR来获取CSRF令牌并将其添加到原始请求的数据对象中。我认为问题是第二个XHR。第二个请求就像第一个请求一样异步,所以你不能只从then
方法返回。
尝试在if
语句中返回第二个XHR生成的承诺(在then
之后的第二个XHR之后在内部return request;
调用中解析。
if(request.url!=verifyCodeUrl && request.data!=undefined){
var secondXhr = VerifyCodeService.getCode()
.then(function(data) {
if (AppConst.serviceResponseOk==data.result) {
request.data.verifyCode = data.verifyCode;
return request;
} else {
console.log('error');
return request;
}
}, function(error) {
console.log('error:' + error);
return request;
});
return secondXhr;
} else {
return request;
}
来自Angular文档的Interceptors section(添加了粗体):
请求:使用http配置对象调用拦截器。该 函数可以自由修改配置对象或创建新对象。该 函数需要直接返回配置对象,或承诺 包含配置或新的配置对象。
另一方面,看起来你在每个XHR中引入了一个重要的延迟,因为在返回令牌之前你基本上阻止了每个请求。
每个响应返回标头中下一个请求的新标记的不同实现可以工作(只要您没有并发请求(!)),或每页加载CSRF标记(如果您有完整页面)重新加载)可能是选项。如果您想进行更改,我确信互联网上有建议。