我一直在寻找一些类似的问题来寻找答案,但我找不到。我有一个节点.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(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中一样。我做错了什么?
更新
忘记发布我的令牌拦截器服务:
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);
}
};
});
虽然我仍然看不出有什么问题。这应该是每次角度视图更改时检查从服务器发送的授权令牌的一种方法。
将最后一个更改为
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
我正在将所有对外部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");
});
};
它使用方便的节点包处理它的 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);
});
});
当然,服务器有权执行任何类型的请求。我希望这对那里的任何人都有帮助。