我使用 ngResource 在 Amazon Web Services 上调用 REST API 时遇到此错误:
XMLHttpRequest 无法加载 http://server.apiurl.com:8000/s/login?login=facebook。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问源“http://localhost”。错误 405
服务:
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
的标头。
您遇到了 CORS 问题。
有几种方法可以解决/解决此问题。
关闭 CORS。例如:如何在 chrome 中关闭 cors 为您的浏览器使用插件 使用 nginx 等代理。如何设置的示例 完成服务器的必要设置。这更多是您在 EC2 实例上加载的 Web 服务器的一个因素(假设这就是您所说的“Amazon Web 服务”)。对于您的特定服务器,您可以参考启用 CORS 网站。
更详细地说,您正在尝试从 localhost 访问 api.serverurl.com。这就是跨域请求的准确定义。
通过关闭它只是为了完成您的工作(好的,但是如果您访问其他网站并且只是在路上踢罐子,那么您的安全性会很差)或者您可以使用代理,让您的浏览器认为所有请求都来自本地主机当你真的有本地服务器然后调用远程服务器时。
所以 api.serverurl.com 可能会变成 localhost:8000/api 并且您的本地 nginx 或其他代理将发送到正确的目的地。
现在应大众需求,100% more CORS info....同样美味!
绕过 CORS 正是那些只学习前端的人所展示的。 https://codecraft.tv/courses/angular/http/http-with-promises/
我的“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');
在 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();
});
});
.
.
.
}
和
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// Shows UseCors with named policy.
app.UseCors("AllowAllHeaders");
.
.
.
}
并将 [EnableCors("AllowAllHeaders")]
放在控制器上。
关于 CORS,有一些注意事项。首先,它不允许使用通配符 *
,但不要让我坚持我在某处读过它,但现在找不到这篇文章。
如果您从其他域发出请求,则需要添加允许来源标头。
Access-Control-Allow-Origin: www.other.com
如果您发出的请求会影响 POST/PUT/PATCH 等服务器资源,并且如果 mime 类型不同于以下 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
,则浏览器将自动发出飞行前 OPTIONS 请求以检查服务器是否允许。
因此,您的 API/服务器需要相应地处理这些 OPTIONS 请求,您需要使用相应的 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 标头很重要,在我的情况下,没有它就无法工作,我猜浏览器需要“访问权限”有效时间的信息。
此外,如果您使用来自不同域的 application/json
mime 发出例如 POST
请求,您还需要添加前面提到的 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
标头,都应在响应中给出以使其正常工作。
this link 上的 MDN 文档中有一个很好的示例,您还应该查看 this SO post
.AllowCredentials()
。添加 .AllowCredentials()
后一切正常。
如果您正在编写 chrome 扩展
您必须在 manifest.json
中为您的域添加权限。
"permissions": [
"http://example.com/*",
"https://example.com/*",
"http://www.example.com/*",
"https://www.example.com/*"
]
JavaScript XMLHttpRequest 和 Fetch 遵循同源策略。因此,使用 XMLHttpRequest 或 Fetch 的 Web 应用程序只能向其自己的域发出 HTTP 请求。
来源:https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
您必须从服务器端发送 Access-Control-Allow-Origin: * HTTP 标头。
如果您使用 Apache 作为您的 HTTP 服务器,那么您可以将其添加到您的 Apache 配置文件中,如下所示:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Mod_headers 在 Apache 中默认启用,但是,您可能希望通过运行以下命令来确保它已启用:
a2enmod headers
/etc/apache2/apache2.conf
C:\Program Files\Apache\Apache2\conf\httpd.conf
,您可以在 httpd.apache.org/docs/2.0/platform/windows.xml 中找到更多详细信息
在 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: *");
...
header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
时有效
要修复 Node JS 应用程序中的跨域请求问题:
npm i cors
只需将以下几行添加到 app.js
let cors = require('cors')
app.use(cors())
如果您偶然使用 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';
有了所有这些帖子,获取等,都可以正常工作。
我们的团队偶尔会使用 Vue、axios 和 C# WebApi 看到这一点。在您尝试命中的端点上添加路由属性可以为我们修复它。
[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }
对于那些使用 Lambda 集成代理和 API 网关的用户。您需要像直接向其提交请求一样配置您的 lambda 函数,这意味着该函数应正确设置响应标头。 (如果您使用自定义 lambda 函数,这将由 API Gateway 处理。)
//In your lambda's index.handler():
exports.handler = (event, context, callback) => {
//on success:
callback(null, {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*"
}
}
}
对于使用 Api Gateway 的 HTTP API 和代理路由 ANY /{proxy+} 的任何人
您需要明确定义路由方法才能使 CORS 正常工作。
https://i.stack.imgur.com/hwmy3.png
希望这在 AWS Docs for Configuring CORS for an HTTP API 中更明确
与 AWS Support 进行了 2 小时的通话,他们联系了一位提出此建议的高级 HTTP API 开发人员。
希望这篇文章可以为那些使用 Api Gateway HTTP API 的人节省一些时间和精力。
在我的 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]
我认为从 Chrome 中禁用 CORS 并不是一个好方法,因为如果您在 ionic 中使用它,那么在 Mobile Build 中肯定会再次出现问题。
所以最好在你的后端修复。
首先在标题中,您需要设置-
header('Access-Control-Allow-Origin: *');
header('标头集 Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept"');
如果 API 的行为既是 GET 又是 POST ,那么还要在你的标题中设置 -
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");退出(0); }
此错误的一个非常常见的原因可能是主机 API 已将请求映射到 http 方法(例如 PUT)并且 API 客户端正在使用不同的 http 方法(例如 POST 或 GET)调用 API
PUT
方法
跨域资源共享 (CORS) 是一种基于 HTTP 标头的机制,它允许服务器指示除其自身之外的任何来源(域、方案或端口),浏览器应允许从这些来源加载资源
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
简而言之 - 网络服务器会告诉您(您的浏览器)您应该信任哪些站点以使用该站点。
Scammysite.bad 试图告诉你的浏览器向 good-api-site.good 发送请求 good-api-site.good 告诉你的浏览器它应该只信任 other-good-site.good 你的浏览器说你真的不应该信任scammysite.bad 对 good-api-site.good 的请求和去 CORS 救了你。
如果您正在创建一个站点,并且您真的不在乎谁与您集成。继续犁。在 ACL 中设置 *
。
但是,如果您正在创建一个站点,并且应该只允许站点 X,甚至站点 X、Y 和 Z,则使用 CORS 指示客户端浏览器仅信任这些站点以与您的站点集成。
浏览器当然可以选择忽略这一点。同样,CORS 保护您的客户 - 而不是您。
CORS 允许定义 *
或 一个 站点。这可能会限制您,但您可以通过向您的 Web 服务器添加一些动态配置来解决此问题 - 和 帮助您做到具体。
这是一个关于如何在 Apache 中配置 CORS pr 站点的示例:
# 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>
当 DNS 服务器设置为 8.8.8.8(谷歌的)时,我遇到了这个问题。实际上,问题出在路由器上,我的应用程序试图通过谷歌连接服务器,而不是本地连接(对于我的特殊情况)。我已经删除了 8.8.8.8,这解决了这个问题。我知道CORS设置解决了这个问题,但也许有人会遇到和我一样的麻烦
我正在使用 AWS sdk 进行上传,在花了一些时间在线搜索之后,我偶然发现了这个线程。感谢@lsimoneau 45581857,事实证明完全相同的事情正在发生。我只是通过附加区域选项将我的请求 URL 指向我存储桶上的区域,它就起作用了。
const s3 = new AWS.S3({
accessKeyId: config.awsAccessKeyID,
secretAccessKey: config.awsSecretAccessKey,
region: 'eu-west-2' // add region here });
https://i.stack.imgur.com/AO86o.png
使用 API 网关中的 Cors 选项,我使用了上面显示的以下设置
另外,请注意,您的函数必须返回 HTTP 状态 200 以响应 OPTIONS 请求,否则 CORS 也会失败。
GeoServer 的独立发行版包括 Jetty 应用程序服务器。启用跨域资源共享 (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>
只需几个步骤即可轻松解决此问题,无需担心任何事情。请按照步骤解决。
打开(https://www.npmjs.com/package/cors#enabling-cors-pre-flight)去安装并复制命令 npm install cors 通过节点终端安装去简单使用(启用所有 CORS 请求)通过滚动。然后将完整的声明复制并粘贴到您的项目中并运行它...这肯定会起作用..复制注释代码并粘贴到您的 app.js 或任何其他项目中并试一试..这将起作用。这将解锁每个跨源资源共享..所以我们可以在服务之间切换供您使用
我成功了,将 OPTIONS 方法添加到 Access-Control-Allow-Methods
Access-Control-Allow-Methods: GET, OPTIONS
但是!再次,这适用于 Chrome、Firefox,但遗憾的是不适用于 Chromium
对预检请求的响应未通过访问控制检查正是问题所在:
在发出实际的 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]
链接到 great read
很容易错过的东西...
在解决方案资源管理器中,右键单击 api-project。在属性窗口中将“匿名身份验证”设置为已启用!!!
禁用 chrome 安全性。创建 chrome 快捷方式右键单击 -> 属性 -> 目标,粘贴此“C:\Program Files (x86)\Google\Chrome\Application\chrome.exe” --disable-web-security --user -data-dir="c:/chromedev"
不定期副业成功案例分享