为什么 $http 不设置默认值 header?

Why won't $http set a default header?

$http.post('http://localhost:7001/v1/sessions', {
  data: {
    username: $scope.user.username,
    password: $scope.user.password,
    type: 'sessions'
  }
})
.then(function(response) {
  if(response.data.data.token) {
    $http.defaults.headers.common.Authorization = response.data.data.token;
    $state.go('app.dashboard');
  } else {
    $scope.authError = response;
  }
}, function(x) {
  $scope.authError = 'Server Error';
});

我可以确认 if 条件被调用并且 response.data.data.token 存在。

它进入app.dashboard状态但被我拦截ui-router:

$stateProvider.state('app', {
  abstract: true,
  url: '/app',
  templateUrl: 'tpl/app.html',
  resolve: {
    current_user: ['$http', function($http) {
      return $http.get('http://localhost:7001/v1/users/4/entities');
    }]
  }
})

但是,该调用在 header 中没有任何设置。我认为 $http.defaults 会在 header 中设置默认值。我做错了什么?

您必须在 config 方法中设置默认值 headers 而不是在您的 service 中。

示例:

myApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
}]);

只有在config你可以配置httpProvider。如果您尝试在您的服务中这样做,它根本不会影响 $httpProvider 服务。

编辑:

您必须在这种情况下使用拦截器。

For purposes of global error handling, authentication, or any kind of synchronous or asynchronous pre-processing of request or postprocessing of responses, it is desirable to be able to intercept requests before they are handed to the server and responses before they are handed over to the application code that initiated these requests.

Refer Angular Docs拦截器部分

只是一些示例代码:

app.service('APIInterceptor', function($rootScope, UserService) {
    var service = this;

    service.request = function(config) { 
       // check if the token is available. Once the token is available get it here from the UserService.
        var access_token = UserService.getToken() || "unauthorized";
        if (access_token) {
            config.headers.authorization = access_token;
        }
        return config;
    };

    service.responseError = function(response) {
        return response;
    };
})

在你的config

$httpProvider.interceptors.push('APIInterceptor');

我更希望您使用可共享数据的服务。

代码

app.service(dataService, function(){
   this.data = {}
   this.getData = function(){
      return data;
   };

   this.setTokenData = function(token){
      data.token = token;
   }
});

现在您的代码将在设置令牌时使用 dataService

  if(response.data.data.token) {
    dataService.setTokenData(response.data.data.token);
    $http.defaults.headers.common.Authorization = dataService.data.token; //dataService.getData().token;
    $state.go('app.dashboard');
  } else {
    $scope.authError = response;
  }

然后您可以使用服务解析

$stateProvider.state('app', {
  abstract: true,
  url: '/app',
  templateUrl: 'tpl/app.html',
  resolve: {
    current_user: ['$http', 'dataService', function($http, dataService) {
      $http.defaults.headers.common.Authorization = dataService.getData().token;
      return $http.get('http://localhost:7001/v1/users/4/entities');
    }]
  }
})