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

因为如果我理解正确,您的用户令牌总是取自 localstorage,您可以在运行函数中设置对该 localStorage 键的监视(Demo plunker for working with Localstorage in 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;
    });
});

这应该可以在没有任何拦截器等的情况下解决您的问题。

但是,我实际上建议使用 http 拦截器,因为对 localStorage 的调用很,或者设置默认值,您在登录或注销后实际设置用户令牌的位置(也将其保存在范围变量中,并像您一样在运行部分初始化它现在)。

于 2014-11-07T21:03:16.530 回答
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 回答
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 回答