javascript AngularJS CORS 请求自定义标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24363907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS CORS request custom header
提问by mmjmanders
I'm having trouble getting CORS enabled on my server in combination with AngularJS. I'm using Angular 1.2.16 and this is my server config:
我在与 AngularJS 结合使用时无法在我的服务器上启用 CORS。我使用的是 Angular 1.2.16,这是我的服务器配置:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name, Authorization"
Header set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Credentials "true"
I can use the following request:
我可以使用以下请求:
$http.post(configuration.authUrl, {username: 'username', password: 'password'})
.success(function (data) {
$cookieStore.put(configuration.sessionName, {
token: data.authenticationToken,
user: data.user
});
})
.error(function () {}));
since this request doesn't use a custom header.
因为此请求不使用自定义标头。
When I afterwards try to request the following:
Balance.get()
with Balance being:
当我之后尝试请求以下内容时:
Balance.get()
平衡是:
angular.module('portalApp')
.factory('Balance', ['$resource', 'Auth', 'configuration', function ($resource, Auth, configuration) {
return $resource(configuration.balanceUrl, {}, {
get: {
method: 'GET',
isArray: false,
headers: {
Authorization: Auth.getAuthToken()
}
}
});
}]);
I get a 401 Unauthorized
on the balanceUrl.
我401 Unauthorized
在 balanceUrl 上得到了一个。
In the config I have put:
在我已经放置的配置中:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
I even tried putting $http.defaults.headers.common.Authorization = Auth.getAuthToken();
before the $resource
in the Balance
resource factory but that didn't help.
我甚至试图把$http.defaults.headers.common.Authorization = Auth.getAuthToken();
以前$resource
的Balance
资源工厂,但没有帮助。
The headers being sent to the preflight OPTIONS
request don't have the Authorization
header, no matter what method I use. These are the request headers of the preflight OPTIONS
request.
无论我使用什么方法,发送到预检OPTIONS
请求的Authorization
标头都没有标头。这些是预检OPTIONS
请求的请求标头。
OPTIONS /api/v1.0/user/orders HTTP/1.1
Host: host
Connection: keep-alive
Cache-Control: no-cache
Access-Control-Request-Method: GET
Pragma: no-cache
Origin: origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: referer
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Any suggestions?
有什么建议?
采纳答案by mmjmanders
After much research I found out the problem wasn't occurring because of the AngularJS or Apache configuration. It was a problem in the backend server app (Java). The urls were restricted for all HTTP methods, so when AngularJS wants to execute the preflight OPTIONS
request, the access was denied and a 401
was returned.
经过大量研究,我发现问题不是由于 AngularJS 或 Apache 配置而发生的。这是后端服务器应用程序(Java)中的一个问题。所有 HTTP 方法都限制了 url,因此当 AngularJS 想要执行预检OPTIONS
请求时,访问被拒绝并401
返回 a。
This was fixed by doing:
这是通过执行以下操作修复的:
if(!authenticationService.isTokenValid(glueToken) && !((HttpServletRequest)servletRequest).getMethod().equals(HttpMethod.OPTIONS.toString()) ){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
In stead of:
代替:
if(!authenticationService.isTokenValid(glueToken)){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
回答by Miraage
As I know you can't use Access-Control-Allow-Origin "*"
with Access-Control-Allow-Credentials "true"
.
据我所知,您不能使用Access-Control-Allow-Origin "*"
with Access-Control-Allow-Credentials "true"
。
回答by Oliver
Why not anonymously (don't perform authentication or authorization) allow the options pre-flight request. https://stackoverflow.com/a/21458845/101662
为什么不匿名(不执行身份验证或授权)允许选项飞行前请求。 https://stackoverflow.com/a/21458845/101662
回答by Chris Southam
I'm using quite a different approach but the premise is still the same.
我使用了完全不同的方法,但前提仍然相同。
First try putting Bearer in front of your access token:
首先尝试将 Bearer 放在您的访问令牌前面:
headers: {
Authorization: 'Bearer ' + Auth.getAuthToken()
}
If not try this: app.config may not work if you don't have app set up as a variable, so you may need to adjust.
如果不试试这个:如果你没有将 app 设置为变量,app.config 可能无法工作,所以你可能需要调整。
app.config(
function($httpProvider) {
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
$httpProvider.defaults.headers.common.Authorization = 'Bearer ' + Auth.getAuthToken();
}
);