具有NodeJS GET请求的AngularJS失败 - " Access-Control-Allow-Headers"不允许使用Access-Control-Allow-Headers。

时间:2015-06-19 15:17:26

标签: javascript angularjs node.js http http-headers

我一直在寻找一些类似的问题来寻找答案,但我无法找到答案。我有一个带有express:

的node.js服务器
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Headers");
  next();
});

app.use(express.static(__dirname+'/assets'));
app.use(bodyParser.json());

app.get('/', function(req, res, next) {
  res.sendFile(__dirname + '/public/index.html');
});

AngularJS使用GET请求到REST API。它们由搜索表单中的键盘事件触发。 app.config:

app.config(function ($httpProvider) {
  $httpProvider.defaults.headers.common['Access-Control-Allow-Headers'] = 'Authorization, Access-Control-Allow-Headers';
  $httpProvider.interceptors.push('TokenInterceptor');
});

...请求代码本身:

$scope.requestMovies = function() {
    $http.get('http://www.omdbapi.com/?s=' + $scope.titleToSearch +
     '&type=movie&r=json')
    .success(function(data, status, headers, config) {
      $scope.movies = data.Search;
    })
    .error(function(data, status, headers, config) {
      alert("No movie found");
    });
  };

这个工作正常,直到我将认证添加到我的项目(因此拦截器),从那时起我总是得到一个错误消息
 XMLHttpRequest cannot load http://www.omdbapi.com/?s=darkmovie&type=movie&r=json. Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers.
即使我DID在前端和后端都授权标题。在Firefox中也发生同样的事情,就像在Chrome中一样。我做错了什么?

更新

忘记发布我的TokenInterceptor服务:

app.service('TokenInterceptor', function($q, $window, $location, AuthenticationService) {
  return {
    request: function (config) {
      config.headers = config.headers || {};
      if ($window.sessionStorage.token) {
        config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
      }
      return config;
    },

    requestError: function(rejection) {
      return $q.reject(rejection);
    },

    /* Set Authentication.isAuthenticated to true if 200 received */
    response: function (response) {
      if (response !== null && response.status == 200 && $window.sessionStorage.token && !AuthenticationService.isAuthenticated) {
        AuthenticationService.isAuthenticated = true;    
      }
      return response || $q.when(response);
    },

    /* Revoke client authentication if 401 is received */
    responseError: function(rejection) {
      if (rejection !== null && rejection.status === 401 && ($window.sessionStorage.token || AuthenticationService.isAuthenticated)) {
        delete $window.sessionStorage.token;
        AuthenticationService.isAuthenticated = false;
        $location.path("/");
      }

      return $q.reject(rejection);
    }
  };
});

虽然我仍然没有看到什么是错的。这被认为是每次角度视图改变时检查从服务器发送的授权令牌的方法。

2 个答案:

答案 0 :(得分:0)

将最后一个更改为

res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

答案 1 :(得分:0)

我将所有请求委托给外部 API 客户端。我应该认为这很糟糕(显然是不可能的)。但是因为它第一次工作(我不知道如何或为什么)我保持我的架构。所以现在我基本上做的是:

客户端现在将URL参数发送到服务器:

$scope.requestMovies = function() {
    $http.post('/requestMovies', {title: $scope.titleToSearch})
    .success(function(data, status, headers, config) {
      console.log(data.Search);
      $scope.movies = data.Search;
    })
    .error(function(data, status, headers, config) {
      alert("No movie found");
    });
  };



它使用handy node package处理GET请求:

var Client = require('node-rest-client').Client;
var client = new Client();
//(...)

app.post('/requestMovies', function(req, res, next) {

  client.get('http://www.omdbapi.com/?s=' + req.body.title + '&type=movie&r=json', function(data, response){
    console.log('CLIENT RESPONSE DATA :' + data);
    res.send(data);
  });

});

当然,服务器有权执行任何类型的请求。我希望这可以帮助那里的任何人。