在没有手动刷新的情况下,没有在angularjs XHR请求中设置额外的头参数

时间:2014-10-06 13:16:49

标签: javascript ajax angularjs xmlhttprequest request-headers

我正在尝试在XHR请求中发送额外的标头(带有$ resource的init)。以下是我的配置

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

我正在更改哈希参数(例如,在登录过程之后)以在app中导航。因此,当我在登录过程后发送任何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',并提供错误错误:[$ rootScope:inprog] $摘要已在进行中

Error: [$rootScope:inprog] $digest already in progress

3 个答案:

答案 0 :(得分:2)

您需要设置一个拦截器来改变发送到服务器的每个请求。您可以在文档here中找到更多信息,但实际上您需要在应用上设置工厂服务以添加令牌标头,如下所示:

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');
});

答案 1 :(得分:2)

module.run在应用中的任何其他内容之前执行得很好(但在module.config之后)。那时localStorage会被设定吗?我认为这会在以后发生,这就是为什么你在重新加载页面后看到这个值。

拦截器将成为可能。 您如何在localStorage中设置值?

Fiddle

答案 2 :(得分:2)

因为如果我理解正确你的用户令牌总是来自localstorage,你可以在你的run函数中设置一个关于localStorage键的监视器(Demo plunker用于处理angularst http://plnkr.co/edit/7hP13JAjPybxkRuMZLZ0?p=preview中的Localstorage)

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的调用是,或者设置在登录或注销后实际设置用户令牌的默认值(将其保存在范围内)变量,并像运行一样在运行部件中初始化它。