对飞行前请求的响应没有通过访问控制检查

我得到这个错误使用ngResource调用休息 API在亚马逊网络服务:

XMLHttpRequest无法加载 # EYZ0。应对 飞行前请求未通过门禁检查:否 'Access-Control-Allow-Origin'头出现在被请求的对象上 资源。因此,来源“http://localhost”不允许访问。 错误405 < / em >

服务:

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'
}
});
}]);

控制器:

[...]
loginService.getUser(JSON.stringify(fbObj)),
function (data) {
console.log(data);
},
function (result) {
console.error('Error', result.status);
}
[...]

我用Chrome浏览器。为了解决这个问题,我还能做些什么?

我甚至将服务器配置为接受来自localhost的头文件。

2073903 次浏览

您遇到了歌珥问题。

有几种方法可以修复或解决这个问题。

  1. 关闭CORS。例如:如何在Chrome关闭CORS
  2. 为您的浏览器使用插件
  3. 使用代理,例如nginx。# EYZ1
  4. 完成服务器的必要设置。这更多的是您在EC2实例上加载的web服务器的一个因素(假设这就是您所说的"Amazon web service")。对于特定的服务器,可以参考启用CORS网站。

更详细地说,您试图从本地主机访问api.serverurl.com。这就是跨域请求的确切定义。

通过关闭它来完成你的工作(好吧,但是如果你访问其他网站,你的安全性就差了),或者你可以使用代理,让你的浏览器认为所有的请求都来自本地主机,而实际上你有一个本地服务器,然后调用远程服务器。

所以api.serverurl.com可能变成localhost: 8000 / api,你的本地nginx或其他代理将发送到正确的目的地。


现在根据大众的要求,# eyz0 -同样的好味道!


绕过CORS正是那些简单学习前端的人所展示的。 # EYZ0 < / em >

我的“API服务器”;是一个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');

对于Python 服务器,您可以使用flask-cors插件来启用跨域请求。

看到:# EYZ0

当DNS服务器设置为8.8.8.8(谷歌’s)时,我遇到过这个问题。事实上,问题出在路由器上。我的应用程序试图通过谷歌连接服务器,而不是本地连接(对于我的特定情况)。

我已经删除了8.8.8.8,这解决了这个问题。我知道CORS设置解决了这个问题,但是可能有人会遇到和我一样的问题。

在我的Apache VirtualHost配置文件中,我添加了以下几行:

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"


RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
XMLHttpRequest获取遵循同源策略。所以, 使用XMLHttpRequest或Fetch的web应用程序只能生成HTTP

来源:# EYZ0

您必须从服务器端发送Access-Control-Allow-Origin: * HTTP报头。

如果你使用Apache作为你的HTTP服务器,那么你可以像这样把它添加到你的Apache配置文件中:

<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>

Mod_headers在Apache中默认是启用的,但是,你可能想通过运行以下命令来确保它是启用的:

 a2enmod headers

ASP。网络核心 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();
});
});
.
.
.
}

而且

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// Shows UseCors with named policy.
app.UseCors("AllowAllHeaders");
.
.
.
}

并将[EnableCors("AllowAllHeaders")]放到控制器中。

有些东西很容易被忽略……

解决方案资源管理器中,右键单击api-project。在属性窗口中,将“匿名认证”设置为启用!!

如果你在写一个Chrome扩展

manifest.json文件中,您必须为您的域添加权限。

"permissions": [
"http://example.com/*",
"https://example.com/*",
"http://www.example.com/*",
"https://www.example.com/*"
]

如果您碰巧使用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';

有了这些帖子得到,等等,将工作得很好。

对于那些使用Lambda集成代理与API网关的人,您需要配置lambda函数,就像您直接向它提交请求一样,这意味着函数应该正确地设置响应头。(如果你使用自定义lambda函数,这将由API网关处理。)

// In your lambda's index.handler():
exports.handler = (event, context, callback) => {
// On success:
callback(null, {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*"
}
}
}

在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: *");
...

GeoServer的独立发行版包括码头应用服务器。启用跨源资源共享(CORS)以允许您自己域之外的JavaScript应用程序使用GeoServer。

取消webapps/geoserver/WEB-INF/web.xml中<filter><filter-mapping>的注释:

<web-app>
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

我认为是从Chrome禁用CORS不是一个好方法,因为如果你在离子中使用它,肯定会在移动构建中再次出现问题。

所以最好修改后端。

首先,在header中,需要设置-

  • 标题(“Access-Control-Allow-Origin: *”);
  • header(' header set Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"');

如果API的行为是GET和POST,那么也设置在你的头-

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {if (收取($ _SERVER [' HTTP_ACCESS_CONTROL_REQUEST_METHOD '])) 头(&;Access-Control-Allow-Methods: GET, POST, options &;); 如果收取($ _SERVER [' HTTP_ACCESS_CONTROL_REQUEST_HEADERS '])) 标题(“Access-Control-Allow-Headers: {$ _SERVER [' HTTP_ACCESS_CONTROL_REQUEST_HEADERS ']}“);退出(0);} < / p >

禁用Chrome安全。

创建Chrome快捷方式:右键单击→属性目标。C:\Program Files (x86)\谷歌\Chrome\Application\ Chrome .exe"——disable-web-security user-data-dir =“c: / chromedev"

我正在使用AWS SDK进行上传,在花了一些时间在网上搜索之后,我偶然发现了这个问题。多亏了@lsimoneau 45581857,原来发生了完全相同的事情。

我只是通过附加区域选项将请求URL指向bucket上的区域,它就工作了。

 const s3 = new AWS.S3({
accessKeyId: config.awsAccessKeyID,
secretAccessKey: config.awsSecretAccessKey,
region: 'eu-west-2'  // add region here });

导致这个错误的一个非常常见的原因可能是主机API已经将请求映射到一个HTTP方法(例如,),而API客户端正在使用一个不同的HTTP方法(例如,帖子得到)调用API。

要修复node . js应用程序中的跨源请求问题:

npm i cors

然后简单地将下面的代码添加到app.js文件中:

let cors = require('cors')
app.use(cors())

说到CORS,有一些注意事项。首先,它不允许通配符*,但不要在这一点上束缚我。我在什么地方读过,现在找不到那篇文章了。

如果从不同的域发出请求,则需要添加允许的起源标头。

Access-Control-Allow-Origin: www.other.com

如果您正在发出影响服务器资源的请求,如帖子//PATCH,并且如果MIME类型与下面的application/x-www-form-urlencodedmultipart/form-datatext/plain不同,浏览器将自动发出一个飞行前选项请求,以检查服务器是否允许这样做。

所以你的API/服务器需要相应地处理这些选项请求,你需要响应适当的access control headers和http响应状态码需要是200

标题应该是这样的,根据你的需要调整它们:

   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
Access-Control-Max-Age: 86400

max-age报头很重要,在我的情况下,没有它就不能工作,我猜浏览器需要多长时间的信息“访问权限”;是有效的。

此外,如果你正在制作一个POST请求,使用来自不同域的application/json mime,你还需要添加前面提到的allow origin头,所以它看起来像这样:

   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

当飞行前成功并获得所有需要的信息时,您的实际请求将被提出。

一般来说,无论在初始请求或预飞行请求中请求Access-Control头文件,都应该在响应中给出,以便它能够工作。

中数文档中有一个关于这个链接的很好的例子,您还应该查看这篇Stack Overflow文章

我们的团队使用Vue.jsAxios和c# Web API时偶尔会遇到这种情况。在您试图命中的端点上添加路由属性为我们修复了它。

[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }

解决这个问题很简单,只需要几个步骤,不用担心任何事情。

请遵循以下步骤来解决它。

  1. 打开(# EYZ0)
  2. 进入安装,复制命令npm install cors,通过Node.js安装到终端
  3. 滚动进入“简单用法(启用所有CORS请求)”。然后复制并粘贴完整的声明到您的项目中并运行它…这肯定有用…… 复制注释代码并粘贴在您的app.js或任何其他项目,并尝试…这是可行的。这将解锁每一个跨起源资源共享…所以我们可以在服务器之间切换供您使用

对于任何使用API网关的HTTP API和代理路由代理任何/ {+}的人

为了使CORS工作,您需要显式地定义路由方法。

Enter image description here

我希望这在用于为HTTP API配置CORS的AWS文档中更加明确

我和AWS支持人员打了两个小时的电话,他们把他们的一个高级HTTP API开发人员圈了进来,他提出了这个建议。

Enter image description here

使用API网关中的CORS选项,我使用了上面所示的以下设置。

另外,请注意,函数必须返回HTTP状态200以响应OPTIONS请求,否则CORS也会失败。

跨源资源共享(Cross-Origin Resource Sharing, CORS)是一种基于http头的机制,它允许服务器指明除自己以外的任何源(域、方案或端口),浏览器<强> < / >强应该允许从这些源加载资源

从# EYZ0

简而言之,web服务器<强> < / >强告诉您(您的浏览器)使用<强> < / >强站点应该信任哪些站点。

  1. Scammysite.bad尝试告诉浏览器向good-api-site.good发送请求
  2. good-api-site.good告诉浏览器它应该只信任other-good-site.good
  3. 你的浏览器说你真的不应该相信scammysite.badgood-api-site.good的请求,而是CORS救了你

如果你是创建网站,你真的不关心谁与你集成。犁。在ACL中设置*

< >强然而< / >强,如果你正在创建一个网站,只有网站X,甚至网站X, Y和Z应该被允许,你使用CORS到指示客户端浏览器,只信任这些网站与你的网站集成。

浏览器当然可以选择忽略这一点。再次强调,CORS保护的是你的客户,而不是你。

CORS允许定义*一个站点。这可能会限制你,但你可以通过在你的web服务器上添加一些动态配置来解决这个问题——而且可以帮助你变得具体。

这是一个关于如何在Apache中为每个站点配置CORS的示例:

# Save the entire "Origin" header in Apache environment variable "AccessControlAllowOrigin"
# Expand the regex to match your desired "good" sites / sites you trust
SetEnvIfNoCase Origin "^https://(other-good-site\.good|one-more-good.site)$" AccessControlAllowOrigin=$0
# Assuming you server multiple sites, ensure you apply only to this specific site
<If "%{HTTP_HOST} == 'good-api-site.com'">
# Remove headers to ensure that they are explicitly set
Header        unset Access-Control-Allow-Origin   env=AccessControlAllowOrigin
Header        unset Access-Control-Allow-Methods  env=AccessControlAllowOrigin
Header        unset Access-Control-Allow-Headers  env=AccessControlAllowOrigin
Header        unset Access-Control-Expose-Headers env=AccessControlAllowOrigin
# Add headers "always" to ensure that they are explicitly set
# The value of the "Access-Control-Allow-Origin" header will be the contents saved in the "AccessControlAllowOrigin" environment variable
Header always set Access-Control-Allow-Origin   %{AccessControlAllowOrigin}e     env=AccessControlAllowOrigin
# Adapt the below to your use case
Header always set Access-Control-Allow-Methods  "POST, GET, OPTIONS, PUT"        env=AccessControlAllowOrigin
Header always set Access-Control-Allow-Headers  "X-Requested-With,Authorization" env=AccessControlAllowOrigin
Header always set Access-Control-Expose-Headers "X-Requested-With,Authorization" env=AccessControlAllowOrigin
</If>

我使它工作,添加选项方法Access-Control-Allow-Methods:

Access-Control-Allow-Methods: GET, OPTIONS

# EYZ0 !同样,这适用于Chrome和Firefox,但遗憾的是不适用于

“对飞行前请求的响应未通过访问控制检查”;正是问题所在:

在发出实际的GET请求之前,浏览器会检查服务是否为CORS正确配置。这是通过检查服务是否接受实际请求将使用的方法和头来完成的。因此,允许从不同的来源访问服务是不够的,还必须满足其他必要条件。

将报头设置为

Header always set Access-Control-Allow-Origin: www.example.com
Header always set Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
Header always set Access-Control-Allow-Headers: Content-Type #etc...

这还不够。你必须添加一个重写规则:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

很好的阅读Response for preflight does not have HTTP ok status