我使用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的头文件。


当前回答

如果您碰巧使用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等都可以正常工作。

其他回答

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

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

在ASP。NET Core Web API,这个问题通过添加“Microsoft.AspNetCore. NET”得到了解决。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");
    .
    .
    .
}

并在控制器中放入[EnableCors("AllowAllHeaders")]。

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

npm i cors

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

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

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

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

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

如果您正在发出影响服务器资源的请求,如POST/PUT/PATCH,并且如果MIME类型不同于以下应用程序/x-www-form-urlencoded, multipart/form-data或text/plain,浏览器将自动发出一个pre-flight OPTIONS请求,以检查服务器是否允许这样做。

所以你的API/服务器需要相应地处理这些OPTIONS请求,你需要用适当的访问控制头进行响应,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头,都应该在响应中给出,以便它能够工作。

在MDN文档中有一个很好的例子,你也应该看看Stack Overflow的帖子。

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

Access-Control-Allow-Methods: GET, OPTIONS

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