3

XHR リクエストで追加のヘッダーを送信しようとしています ($resource で初期化)。以下は私の構成です。

var app = angular.module('app',['angularMoment']).
run(function ($rootScope,$location,$route, $timeout, $http) { 
    var token = localStorage.getItem("userToken");
    $http.defaults.headers.common.token = token;
}

アプリ内をナビゲートするためにハッシュ パラメータを変更しています (ログイン プロセス後など)。そのため、ログイン プロセス後に (手動リロードなしで) XHR リクエストを送信すると、トークン(リクエスト ヘッダー) がNULLとして送信されます。しかし、ページを手動でリロードすると、正常に機能します (つまり、トークンをヘッダーとして送信します)。また、試してみまし$route.reload()たが、機能しません。

この問題を解決する方法を教えてください。

ありがとう

編集 :

次のコードで試した後:

app.factory('tokenInterceptorService', ['$q', '$location', function ($q, $location) {

var tokenInterceptor = {};

var request = function (config) {

    config.headers = config.headers || {};

    var token = localStorage.getItem("userToken");

    config.headers.token = token;

    return config;
}

// if response errors with 401 redirect to lgoin
var response = function (rejection) {
    if (rejection.status === 401) {
        $location.path('/');
    }
    return $q.reject(rejection);
}

tokenInterceptor.request = request;
tokenInterceptor.response = response;

return tokenInterceptor;
}]);

app.config(function ($httpProvider) {
$httpProvider.interceptors.push('tokenInterceptorService');
});

app.run(function ($rootScope, $location,$route, $timeout, $http) {

$rootScope.config = {};
$rootScope.config.app_url = $location.url();
$rootScope.config.app_path = $location.path();
$rootScope.layout = {};
$rootScope.layout.loading = false;


$rootScope.$on('$routeChangeStart', function () {
    //need to validate
    console.log($rootScope.isValidated + "app");

    //show loading 
    $timeout(function(){
      $rootScope.layout.loading = true;          
    });
});
$rootScope.$on('$routeChangeSuccess', function () {
    //hide loading 
    $timeout(function(){
      $rootScope.layout.loading = false;
    }, 200);
});
$rootScope.$on('$routeChangeError', function () {

    alert('Something went wrong. Please refresh.');
    $rootScope.layout.loading = false;

});
})

「 .run 」を使用してアプリケーション内のビューをレンダリングするのを停止し、トラップし$rootScope.$on('$routeChangeError',てエラーError: [$rootScope:inprog] $digest already in progress を発生させます。

エラー: [$rootScope:inprog] $digest は既に進行中です

4

3 に答える 3

2

私が正しく理解していれば、ユーザートークンは常にローカルストレージから取得されるため、実行関数でそのローカルストレージキーに監視を設定できます (Angular でローカルストレージを操作するためのデモプランカー: http://plnkr.co/edit/7hP13JAjPybxkRuMZLZ0?p =プレビュー)

angular.module('app',[]).run(['$rootScope', '$http', function($root, $http) {
    $root.$watch(function() {
          return localStorage.getItem('userToken');
    }, function(userToken) {
       $http.defaults.headers.common.token = userToken;
    });
});

これにより、インターセプターなどを使用せずに問題を解決できるはずです。

ただし、localStorageへの呼び出しが遅いため、httpインターセプターを使用するか、ログインまたはログアウト後にユーザートークンを実際に設定するデフォルトを設定することをお勧めします(スコープ変数にも保存し、実行部分で初期化します今)。

于 2014-11-07T21:03:16.530 に答える
2

module.run executes well before anything else in the app (but after module.config). Would the localStorage have been set by then? I think that is happening later, which is why you see this value after reloading the page.

An interceptor would be the way to go. How are you setting the value in localStorage?

Fiddle

于 2014-11-06T04:49:51.253 に答える
2

サーバーに送信されるすべてのリクエストを変更するインターセプターをセットアップする必要があります。詳細については、こちらのドキュメントを参照してください。ただし、基本的には、アプリにファクトリ サービスをセットアップして、次のようにトークン ヘッダーを追加する必要があります。

app.factory('tokenInterceptorService', ['$q', '$location', 'localStorage', function ($q, $location, localStorage) {

    var tokenInterceptor = {};

    var request = function (config) {

        config.headers = config.headers || {};

        var token = localStorage.getItem("userToken");
        if (token) {
            config.headers.token = token;
        }

        return config;
    }

    // if response errors with 401 redirect to lgoin
    var response = function (rejection) {
        if (rejection.status === 401) {
            $location.path('/login');
        }
        return $q.reject(rejection);
    }

    tokenInterceptor.request = request;
    tokenInterceptor.response = response;

    return tokenInterceptor;
}]);

次に、構成段階で次のように登録します。

app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('tokenInterceptorService');
});
于 2014-10-06T13:48:59.937 に答える