Javascript 对预检请求的响应未通过访问控制检查
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35588699/
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
Response to preflight request doesn't pass access control check
提问by Andre Mendes
I'm getting this error using ngResource to call a REST API on Amazon Web Services:
我使用 ngResource 在 Amazon Web Services 上调用 REST API 时遇到此错误:
XMLHttpRequest cannot load http://server.apiurl.com:8000/s/login?login=facebook. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. Error 405
XMLHttpRequest 无法加载 http://server.apiurl.com:8000/s/login?login=facebook。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问Origin ' http://localhost'。 错误 405
Service:
服务:
socialMarkt.factory('loginService', ['$resource', function($resource){
var apiAddress = "http://server.apiurl.com:8000/s/login/";
return $resource(apiAddress, { login:"facebook", access_token: "@access_token" ,facebook_id: "@facebook_id" }, {
getUser: {method:'POST'}
});
}]);
Controller:
控制器:
[...]
loginService.getUser(JSON.stringify(fbObj)),
function(data){
console.log(data);
},
function(result) {
console.error('Error', result.status);
}
[...]
I'm using Chrome, and I dont know what else to do in order to fix this problem. I've even configured the server to accept headers from origin localhost
.
我正在使用 Chrome,但我不知道还能做些什么来解决这个问题。我什至将服务器配置为接受来自 origin 的标头localhost
。
采纳答案by E. Maggini
You are running into CORS issues.
您遇到了 CORS 问题。
There are several ways to fix/workaround this.
有几种方法可以解决/解决此问题。
- Turn off CORS. For example: how to turn off cors in chrome
- Use a plugin for your browser
- Use a proxy such as nginx. example of how to set up
- Go through the necessary setup for your server. This is more a factor of the web server you have loaded on your EC2 instance (presuming this is what you mean by "Amazon web service"). For your specific server you can refer to the enable CORS website.
- 关闭 CORS。例如:如何在 chrome 中关闭 cors
- 为您的浏览器使用插件
- 使用代理,例如 nginx。如何设置的示例
- 为您的服务器完成必要的设置。这更多是您在 EC2 实例上加载的 Web 服务器的一个因素(假设这就是您所说的“Amazon Web 服务”)。对于您的特定服务器,您可以参考启用 CORS 网站。
More verbosely, you are trying to access api.serverurl.com from localhost. This is the exact definition of cross domain request.
更详细地说,您正在尝试从本地主机访问 api.serverurl.com。这是跨域请求的确切定义。
By either turning it off just to get your work done (OK, put poor security for you if you visit other sites and just kicks the can down the road) you can use a proxy which makes your browser think all requests come from local host when really you have local server that then calls the remote server.
通过关闭它只是为了完成您的工作(好吧,如果您访问其他网站并且只是在路上踢罐子,那么您的安全性会很差)您可以使用代理,使您的浏览器认为所有请求都来自本地主机你真的有本地服务器,然后调用远程服务器。
so api.serverurl.com might become localhost:8000/api and your local nginx or other proxy will send to the correct destination.
因此 api.serverurl.com 可能会变成 localhost:8000/api 并且您的本地 nginx 或其他代理将发送到正确的目的地。
Now by popular demand, 100% more CORS info....same great taste!
现在应大众需求,CORS 信息增加了100%......同样的美味!
And for the downvoters.... bypassing CORS is exactly what is shown for those simply learning the front end. https://codecraft.tv/courses/angular/http/http-with-promises/
而对于downvoters....绕过CORS正是那些只是学习前端的人所展示的。 https://codecraft.tv/courses/angular/http/http-with-promises/
回答by Slipstream
My "API Server" is an PHP Application so to solve this problem I found the below solution to work:
我的“API 服务器”是一个 PHP 应用程序,因此为了解决这个问题,我找到了以下解决方案:
Place the lines in index.php
将这些行放在index.php 中
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');
回答by Rajkumar Peter
In AspNetCore web api, this issue got fixed by adding "Microsoft.AspNetCore.Cors" (ver 1.1.1) and adding the below changes on Startup.cs.
在 AspNetCore web api 中,通过添加“Microsoft.AspNetCore.Cors”(版本 1.1.1)并在 Startup.cs 上添加以下更改来解决此问题。
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAllHeaders",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
.
.
.
}
and
和
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// Shows UseCors with named policy.
app.UseCors("AllowAllHeaders");
.
.
.
}
and putting [EnableCors("AllowAllHeaders")]
on the controller.
并戴上[EnableCors("AllowAllHeaders")]
控制器。
回答by Sasa Blagojevic
There are some caveats when it comes to CORS. First, it does not allow wildcards *
but don't hold me on this one I've read it somewhere and I can't find the article now.
当涉及到 CORS 时,有一些注意事项。首先,它不允许使用通配符,*
但不要让我坚持这个我在某处读过它,现在找不到这篇文章。
If you are making requests from a different domain you need to add the allow origin headers.
如果您从不同的域发出请求,则需要添加允许源标头。
Access-Control-Allow-Origin: www.other.com
If you are making requests that affect server resources like POST/PUT/PATCH, and if the mime type is different than the following application/x-www-form-urlencoded
, multipart/form-data
, or text/plain
the browser will automatically make a pre-flight OPTIONS request to check with the server if it would allow it.
如果你正在影响服务器资源,如POST / PUT /补丁,如果MIME类型是比下面的不同要求application/x-www-form-urlencoded
,multipart/form-data
或text/plain
浏览器会自动进行飞行前的OPTIONS请求来检查与服务器是否会允许它.
So your API/server needs to handle these OPTIONS requests accordingly, you need to respond with the appropriate access control headers
and the http response status code needs to be 200
.
因此,您的 API/服务器需要相应地处理这些 OPTIONS 请求,您需要以适当的方式进行响应,access control headers
并且 http 响应状态代码需要为200
.
The headers should be something like this, adjust them for your needs:
标题应该是这样的,根据您的需要调整它们:
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
The max-age header is important, in my case, it wouldn't work without it, I guess the browser needs the info for how long the "access rights" are valid.
max-age 标头很重要,在我的情况下,没有它就无法工作,我猜浏览器需要“访问权限”有效期的信息。
In addition, if you are making e.g. a POST
request with application/json
mime from a different domain you also need to add the previously mentioned allow origin header, so it would look like this:
此外,如果您正在POST
使用application/json
来自不同域的 mime进行请求,您还需要添加前面提到的允许源头,因此它看起来像这样:
Access-Control-Allow-Origin: www.other.com
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400
When the pre-flight succeeds and gets all the needed info your actual request will be made.
当预飞行成功并获得所有需要的信息时,您的实际请求将被提出。
Generally speaking, whatever Access-Control
headers are requested in the initial or pre-flight request, should be given in the response in order for it to work.
一般来说,无论Access-Control
是在初始请求还是飞行前请求中请求的头,都应该在响应中给出,以使其工作。
There is a good example in the MDN docs here on this link, and you should also check out this SO post
回答by Tadej
JavaScript XMLHttpRequestand Fetchfollow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain.
JavaScript XMLHttpRequest和Fetch遵循同源策略。因此,使用 XMLHttpRequest 或 Fetch 的 Web 应用程序只能向其自己的域发出 HTTP 请求。
Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
来源:https: //developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
You have to send the Access-Control-Allow-Origin: *HTTP header from your server side.
您必须从服务器端发送Access-Control-Allow-Origin: *HTTP 标头。
If you are using Apache as your HTTP server then you can add it to your Apache configuration file like this:
如果您使用 Apache 作为您的 HTTP 服务器,那么您可以将其添加到您的 Apache 配置文件中,如下所示:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Mod_headers is enabled by default in Apache, however, you may want to ensure it's enabled by running:
Mod_headers 在 Apache 中默认启用,但是,您可能希望通过运行来确保它已启用:
a2enmod headers
回答by freedev
If you're writing a chrome-extension
如果您正在编写chrome 扩展
You have to add in the manifest.json
the permissions for your domain(s).
您必须添加manifest.json
域的权限。
"permissions": [
"http://example.com/*",
"https://example.com/*"
]
回答by Sunil Kumar
If you are using IIS server by chance. you can set below headers in the HTTP request headers option.
如果您偶然使用 IIS 服务器。您可以在 HTTP 请求标头选项中设置以下标头。
Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: 'HEAD, GET, POST, PUT, PATCH, DELETE'
Access-Control-Allow-Headers: 'Origin, Content-Type, X-Auth-Token';
with this all post, get etc., will work fine.
有了这个所有帖子,获取等,将正常工作。
回答by atiruz
In PHP you can add the headers:
在 PHP 中,您可以添加标题:
<?php
header ("Access-Control-Allow-Origin: *");
header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
header ("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header ("Access-Control-Allow-Headers: *");
...
回答by Teriblus
For python flask server, you can use the flask-cors plugin to enable cross domain requests.
对于python的flask服务器,你可以使用flask-cors插件来开启跨域请求。
回答by Rohit Parte
To fix cross-origin-requests issues in a Node JS application:
要修复 Node JS 应用程序中的跨域请求问题:
npm i cors
And simply add the lines below to the app.js
只需将下面的行添加到 app.js
let cors = require('cors')
app.use(cors())