Javascript 请求的资源上不存在“Access-Control-Allow-Origin”标头 + 响应的 HTTP 状态代码为 401
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43989859/
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
No 'Access-Control-Allow-Origin' header is present on the requested resource + The response had HTTP status code 401
提问by Lyle Rolleman
XMLHttpRequest cannot load http://192.168.1.253:8080/... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401.
XMLHttpRequest 无法加载http://192.168.1.253:8080/... 请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问Origin ' http://localhost:4200'。响应的 HTTP 状态代码为 401。
Pretty common error, with a great many possible solutions that haven't worked. I understand (I think) how CORS is supposed to work, and I don't see anything wrong with my HTTP headers, but it still doesn't work
非常常见的错误,有很多可能的解决方案没有奏效。我了解(我认为)CORS 应该如何工作,并且我没有发现我的 HTTP 标头有任何问题,但它仍然不起作用
From Chrome:
从铬:
Request URL:http://192.168.1.253:8080/...
Request Method:OPTIONS
Status Code:200 OK
Remote Address:192.168.1.253:8080
Referrer Policy:no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers:x-requested-with,accept,content-
type,authorization
Access-Control-Allow-Methods:POST, GET, PUT, PATCH, OPTIONS, DELETE
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Connection:keep-alive
Content-Length:0
Date:Mon, 15 May 2017 21:50:55 GMT
Expires:0
Pragma:no-cache
Server:...
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:authorization,content-type
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:192.168.1.253:8080
Origin:http://localhost:4200
Pragma:no-cache
Referer:http://localhost:4200/...
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
My understanding is the OPTIONSresponse needs the Access-Control-Allow-Originheader set and allow the method type and header values, which it does
我的理解是OPTIONS响应需要设置Access-Control-Allow-Origin标头并允许方法类型和标头值,它确实如此
Relevant angular below. I've done a fair number of different combinations of this with all sorts of different stuff in the header, but nothing works
相关角度如下。我已经用标题中的各种不同的东西做了很多不同的组合,但没有任何效果
private getObject<T>(path: string): Promise<T> {
return this.http.get(SERVER_URL + path, this.authenticationToken())
.toPromise()
.then(response => response.json() as T)
.catch(this.handleError);
}
private authenticationToken() : RequestOptions {
let login = JSON.parse(sessionStorage.getItem('currentLogin'));
if (login && login.authenticationToken) {
let headers = new Headers({
'Authorization': 'Basic ' + login.authenticationToken,
'Content-type': 'application/json',
});
return new RequestOptions({ headers: headers });
}
}
I got the feeling I'm missing something obvious but it's driving me nuts, any help is appreciated. Note this does work with a pre-existing Ember application so I don't think it's the server
我觉得我错过了一些明显的东西,但这让我发疯,任何帮助表示赞赏。请注意,这确实适用于预先存在的 Ember 应用程序,因此我认为它不是服务器
回答by sideshowbarker
The response had HTTP status code 401.
响应的 HTTP 状态代码为 401。
401 indicates an authentication error. The error message in the question isn't for a response from a preflight OPTIONSrequest. It instead seems to be for the actual GETrequest you're trying to send.
401 表示认证错误。问题中的错误消息不是针对预检OPTIONS请求的响应。相反,它似乎是针对GET您尝试发送的实际请求。
So based on that error message, it seems the most likely scenario is that the browser's preflight OPTIONSrequest succeeded but your GETrequest is not succeeding due to authentication failure.
因此,根据该错误消息,似乎最有可能的情况是浏览器的预检OPTIONS请求成功,但您的GET请求由于身份验证失败而未成功。
So the server's returning a 401 response/error page. And many/most web servers aren't configured to send the Access-Control-Allow-Originresponse header for error responses/pages. That's the only reason you're also getting a message about that header being missing.
所以服务器返回 401 响应/错误页面。并且许多/大多数 Web 服务器未配置为发送Access-Control-Allow-Origin错误响应/页面的响应标头。这是您还收到有关该标头丢失的消息的唯一原因。
But that missing header for the error response is not the cause of your problem; instead, the 401 is.
但是错误响应缺少的标头不是问题的原因;相反,401 是。
So it seems you probably want to figure out what's causing the server to send a 401 response—why you're getting an authentication failure. If you fix that it seems likely you'll get a response from the server that includes the Access-Control-Allow-Originresponse header as expected.
因此,您似乎想弄清楚是什么导致服务器发送 401 响应——为什么会出现身份验证失败。如果您修复该问题,您似乎很可能会收到来自服务器的Access-Control-Allow-Origin响应,其中包含预期的响应标头。
回答by havelino
This is a typical error found when we work with Angular and Ionic, the problem appears because when your app loaded in a browser on your app loads all the content from an originthat comes from your local address http://localhost:4200, then when you want to make any AJAX request sent out to another host than localhost:4200 the request is called from an any point different from the originits require a CORS(Cross Origin Resource Sharing) preflight request to see if it can access the resource.
这是我们使用 Angular 和 Ionic 时发现的一个典型错误,问题出现是因为当您的应用程序加载到您应用程序的浏览器中时,从您本地地址的来源加载所有内容http://localhost:4200,然后当您想要制作任何 AJAX 时发送到另一台主机localhost:4200 的请求,而不是从与源不同的任何点调用请求,它需要一个CORS(跨源资源共享)预检请求,以查看它是否可以访问资源。
The solution is use a Proxy To Backend, with this you can highHyman certain urls and send them to a backend server. The implementation is easy:
解决方案是使用代理到后端,这样您就可以劫持某些 url 并将它们发送到后端服务器。实现很简单:
1.- Create a file proxy.conf.jsin the root folder of your project.
1.-proxy.conf.js在项目的根文件夹中创建一个文件。
2.- Configure your proxy, inside your proxy.conf.jsfile put this, assuming your new host is in http://localhost:3000.
2.- 配置您的代理,在您的proxy.conf.js文件中放置它,假设您的新主机在http://localhost:3000.
const PROXY_CONFIG = [
{
context: [
"/my",
"/many",
"/endpoints",
"/i",
"/need",
"/to",
"/proxy"
],
target: "http://localhost:3000",
secure: false
}
]
module.exports = PROXY_CONFIG;
3.- Modify your package.jsonfile, inserting this "start": "ng serve --proxy-config proxy.conf.js",
3.- 修改你的package.json文件,插入这个"start": "ng serve --proxy-config proxy.conf.js",
4.- In your Service change a little the path of your request from this http://localhost:3000/endpoints/any/path/that/you/useto this ../endpoints/any/path/that/you/use(assuming the another host is in localhost:3000and the context is /endpoints).
4.- 在您的服务中,将您的请求路径从 thishttp://localhost:3000/endpoints/any/path/that/you/use更改为 this ../endpoints/any/path/that/you/use(假设另一台主机在其中localhost:3000并且上下文是/endpoints)。
5.- Run angular since the root folder with: npm start ; this execute ng serve with the proxy parameters.
5.-由于与根文件夹运行角:npm start ; 这ng serve 与代理参数一起执行。
If you need more information about this please check the Proxy to backend Angular Cli documentation
如果您需要更多关于这方面的信息,请查看Proxy to backend Angular Cli 文档

