2016-01-21 96 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

相關問題