2016-01-21 95 views
0

我想在我的应用程序中使用请求拦截器来将验证代码添加到请求中(用于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

但是我确实在所有情况下都返回请求... – Gatekeeper

回答

1

如果我读了这个权利,您正在制作一个XHR,它触发另一个XHR来获取CSRF令牌并将其添加到原始请求的数据对象。我认为这个问题是第二个XHR。第二个请求与第一个请求是异步的,因此您不能仅从then方法返回。

尝试返回您的if语句中的第二个XHR生成的承诺(在第二个XHR之后调用then内部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; 
      } 

从角文档的Interceptors section(加粗加):

request: interceptors get called with a http config object. The function is free to modify the config object or create a new one. The function needs to return the config object directly, or a promise containing the config or a new config object.

在不同的音符,它看起来像您将引入一个显著延迟到每个XHR因为你是从根本上阻断每个请求直到令牌返回。

一个不同的实现,其中每个响应返回头中下一个请求的新标记可以工作(只要没有并发请求(!)),或者每页加载的CSRF标记(如果您已满页面重新加载)可能是选项。如果你想做出这样的改变,我确信互联网上有建议。

+1

谢谢,我试过,但那还不够,为我工作的解决方案就是您发布的内容,PLUS立即用var deferred = $ q解决承诺。推迟(); deferred.resolve(secondXhr); return deferred.promise; – Gatekeeper

+0

不错,很高兴你把它整理出来! – pherris

相关问题