对预检请求的响应未通过访问控制检查

IT技术 javascript ajax http cors http-status-code-405
2021-01-16 14:57:15

我在使用 ngResource 在 Amazon Web Services 上调用 REST API 时遇到此错误:

XMLHttpRequest 无法加载 http://server.apiurl.com:8000/s/login?login=facebook对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 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,但我不知道还能做什么来解决这个问题。我什至将服务器配置为接受来自 origin 的标头localhost

6个回答

您遇到了 CORS 问题。

有几种方法可以解决/解决此问题。

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

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

通过关闭它只是为了完成您的工作(好吧,但是如果您访问其他站点并且只是在路上踢罐子,那么您的安全性很差)您可以使用代理,使您的浏览器认为所有请求都来自本地主机你真的有本地服务器,然后调用远程服务器。

因此 api.serverurl.com 可能会变成 localhost:8000/api 并且您的本地 nginx 或其他代理将发送到正确的目的地。


现在应大众需求,CORS 信息增加了100% ......同样的美味!


绕过 CORS 正是为那些简单学习前端的人所展示的。 https://codecraft.tv/courses/angular/http/http-with-promises/

我添加了 chrome 插件,它工作了几天。现在它不工作了。
2021-03-17 14:57:15
谢谢你拯救了我的一天。仅使用第一个选项:C:\Program Files (x86)\Google\Chrome\Application>chrome.exe --user-data-dir="C:\Chrome dev session" --disable-web-security。来自:stackoverflow.com/questions/3102819/...
2021-04-01 14:57:15
@Xvegas 您可以在此处查看您的服务器类型。w3.org/wiki/CORS_Enabled
2021-04-08 14:57:15
@JonathanSimas 如前所述,这是继续开发工作的几种方法之一。变通办法是解决方案。你甚至会在我的回答中注意到我说这安全性很差,真的只是把罐子踢倒了。;-)
2021-04-08 14:57:15
在浏览器中禁用 cors?这不是解决方案,而是一种解决方法,对真正需要启用 CORS 的人没有帮助。
2021-04-09 14:57:15

我的“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');
@whatthefish 这是服务器端更改,而不是客户端更改。
2021-03-16 14:57:15
我同意,这比接受的答案要好,尽管在复制这些行时要小心,确保修改方法和来源。
2021-03-22 14:57:15
@CodyBugstein 和 whatthefish 放在任何输出之前
2021-03-23 14:57:15
@AsmaRahimAliJafri 这必须在服务器端完成!
2021-03-24 14:57:15
将它放在 Angular 6 项目中的什么位置?
2021-04-06 14:57:15

在 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 的存在是有原因的。
2021-03-12 14:57:15
只是为了更清楚@paqogomez,在您的 ConfigureServices 方法中: services.AddCors(options => { options.AddPolicy("AllowSpecificOrigin", builder => { builder.WithOrigins(" localhost" ) .AllowAnyOrigin() .AllowAnyHeader() 。 AllowAnyMethod(); }); }); 并在您的配置方法中: app.UseCors("AllowSpecificOrigin");
2021-03-30 14:57:15

关于 CORS,有一些注意事项。首先,它不允许使用通配符,*但不要让我坚持这个我在某处读过它,现在找不到这篇文章。

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

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

如果你正在影响服务器资源,如POST / PUT /补丁,如果MIME类型是比下面的不同要求application/x-www-form-urlencodedmultipart/form-datatext/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 标头很重要,在我的情况下,没有它就无法工作,我猜浏览器需要“访问权限”有效期的信息。

此外,如果您正在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

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

一般来说,无论Access-Control是在初始请求还是飞行前请求中请求的头,都应该在响应中给出,以使其工作。

此链接上的 MDN 文档中有一个很好的示例,您还应该查看此 SO 帖子

这是 Mozilla 文章,讨论如何不能将通配符用于 cors 来源: 链接 显然这仅适用于使用凭据时(如果我理解正确的话)
2021-03-12 14:57:15
我正在使用通配符并提交不记名令牌来授权请求​​并且它工作正常所以不确定我上面提供的链接是指关于凭据的内容。我的问题是,在 .Net Core 中构建我的 CORS 策略时,我没有添加.AllowCredentials(). 添加后.AllowCredentials()一切正常。
2021-04-04 14:57:15

JavaScript XMLHttpRequestFetch遵循同源策略。因此,使用 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
@ShubhamArya 在 linux Debian 上的默认位置是: /etc/apache2/apache2.conf
2021-03-10 14:57:15
我在哪里可以找到我的 Apache 配置文件?
2021-03-22 14:57:15
@Shubham艾莉亚:Windows默认的位置C:\Program Files\Apache\Apache2\conf\httpd.conf,你可以找到更多的细节httpd.apache.org/docs/2.0/platform/windows.xml
2021-03-31 14:57:15
我在哪里可以在 Windows 中找到它?
2021-04-01 14:57:15