我使用ngResource在亚马逊Web服务上调用REST API得到这个错误:

XMLHttpRequest无法加载 http://server.apiurl.com: 8000 / s /登录吗? =登录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的头文件。


当前回答

如果你在写一个Chrome扩展

在舱单上。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';

所有这些POST、GET等都可以正常工作。

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

来自跨原产地资源共享(CORS)

简而言之,网络服务器会告诉你(你的浏览器)你应该信任哪些网站。

Scammysite。Bad尝试告诉浏览器向good-api-site.good发送请求 good-api-site。Good告诉浏览器它应该只信任other-good-site.good 你的浏览器说你真的不应该相信诈骗网站。Bad对good-api-site的请求。很好,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>

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

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

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

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

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

Access-Control-Allow-Methods: GET, OPTIONS

但是!同样,这在Chrome和Firefox中都有效,但遗憾的是在Chromium中行不通。