【问题标题】:AngularJS with NodeJS GET request fails - "Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers"带有 NodeJS GET 请求的 AngularJS 失败 - “Access-Control-Allow-Headers 不允许 Access-Control-Allow-Headers”
【发布时间】:2015-09-05 15:32:14
【问题描述】:

我一直在寻找一些类似的问题以寻找答案,但找不到。我有一个带有 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。它们由搜索表单中的 keyup 事件触发。 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.
即使我确实授权了前端和后端的标头。 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);
    }
  };
});

虽然我仍然看不出有什么问题。这应该是一种在每次角度视图发生变化时检查服务器发送的授权令牌的方法。

【问题讨论】:

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


    【解决方案1】:

    把最后一个改成

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

    【讨论】:

    • 没有让事情变得更糟,但也没有解决问题
    • 尝试将 headers.common 修改为 $httpProvider.defaults.headers.common['Access-Control-Allow-Headers'] = '*';
    • 我在之前的迭代中也尝试过,但没有成功。有趣的事实:我注意到每个请求都是作为 OPTIONS 而不是 GET 发送的。不幸的是,我不记得是现在才发生还是以前发生过
    • 嗯,在某些情况下,access-control-allow-headers 显然不支持通配符。也许尝试将客户端和服务器端都配置为接受相同的标头?
    • 是的,两者都有。奇怪的是,这以前有效。它把我逼到了精神错乱的边缘......
    【解决方案2】:

    我将 所有请求 委托给 EXTERNAL API 给 CLIENT。我应该认为这很糟糕(而且显然是不可能的)。但自从它第一次工作(我不知道如何或为什么)我保持我的架构这样。所以现在基本上我要做的是:

    客户端现在将 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);
      });
    
    });
    

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

    【讨论】:

      猜你喜欢
      • 2016-11-24
      • 2015-06-17
      • 2016-05-15
      • 2015-06-03
      • 2016-09-30
      • 2013-07-05
      • 1970-01-01
      • 2014-11-30
      相关资源
      最近更新 更多