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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35588699/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:56:08  来源:igfitidea点击:

Response to preflight request doesn't pass access control check

javascriptajaxhttpcorshttp-status-code-405

提问by Andre Mendes

I'm getting this error using ngResource to call a REST API on Amazon Web Services:

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

XMLHttpRequest cannot load http://server.apiurl.com:8000/s/login?login=facebook. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. Error 405

XMLHttpRequest 无法加载 http://server.apiurl.com:8000/s/login?login=facebook。对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问Origin ' http://localhost'。 错误 405

Service:

服务:

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

Controller:

控制器:

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

I'm using Chrome, and I dont know what else to do in order to fix this problem. I've even configured the server to accept headers from origin localhost.

我正在使用 Chrome,但我不知道还能做些什么来解决这个问题。我什至将服务器配置为接受来自 origin 的标头localhost

采纳答案by E. Maggini

You are running into CORS issues.

您遇到了 CORS 问题。

There are several ways to fix/workaround this.

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

  1. Turn off CORS. For example: how to turn off cors in chrome
  2. Use a plugin for your browser
  3. Use a proxy such as nginx. example of how to set up
  4. Go through the necessary setup for your server. This is more a factor of the web server you have loaded on your EC2 instance (presuming this is what you mean by "Amazon web service"). For your specific server you can refer to the enable CORS website.
  1. 关闭 CORS。例如:如何在 chrome 中关闭 cors
  2. 为您的浏览器使用插件
  3. 使用代理,例如 nginx。如何设置的示例
  4. 为您的服务器完成必要的设置。这更多是您在 EC2 实例上加载的 Web 服务器的一个因素(假设这就是您所说的“Amazon Web 服务”)。对于您的特定服务器,您可以参考启用 CORS 网站。

More verbosely, you are trying to access api.serverurl.com from localhost. This is the exact definition of cross domain request.

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

By either turning it off just to get your work done (OK, put poor security for you if you visit other sites and just kicks the can down the road) you can use a proxy which makes your browser think all requests come from local host when really you have local server that then calls the remote server.

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

so api.serverurl.com might become localhost:8000/api and your local nginx or other proxy will send to the correct destination.

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



Now by popular demand, 100% more CORS info....same great taste!

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



And for the downvoters.... bypassing CORS is exactly what is shown for those simply learning the front end. https://codecraft.tv/courses/angular/http/http-with-promises/

而对于downvoters....绕过CORS正是那些只是学习前端的人所展示的。 https://codecraft.tv/courses/angular/http/http-with-promises/

回答by Slipstream

My "API Server" is an PHP Application so to solve this problem I found the below solution to work:

我的“API 服务器”是一个 PHP 应用程序,因此为了解决这个问题,我找到了以下解决方案:

Place the lines in index.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');

回答by Rajkumar Peter

In AspNetCore web api, this issue got fixed by adding "Microsoft.AspNetCore.Cors" (ver 1.1.1) and adding the below changes on Startup.cs.

在 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();
                });
    });
    .
    .
    .
}

and

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{


    // Shows UseCors with named policy.
    app.UseCors("AllowAllHeaders");
    .
    .
    .
}

and putting [EnableCors("AllowAllHeaders")]on the controller.

并戴上[EnableCors("AllowAllHeaders")]控制器。

回答by Sasa Blagojevic

There are some caveats when it comes to CORS. First, it does not allow wildcards *but don't hold me on this one I've read it somewhere and I can't find the article now.

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

If you are making requests from a different domain you need to add the allow origin headers.

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

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

If you are making requests that affect server resources like POST/PUT/PATCH, and if the mime type is different than the following application/x-www-form-urlencoded, multipart/form-data, or text/plainthe browser will automatically make a pre-flight OPTIONS request to check with the server if it would allow it.

如果你正在影响服务器资源,如POST / PUT /补丁,如果MIME类型是比下面的不同要求application/x-www-form-urlencodedmultipart/form-datatext/plain浏览器会自动进行飞行前的OPTIONS请求来检查与服务器是否会允许它.

So your API/server needs to handle these OPTIONS requests accordingly, you need to respond with the appropriate access control headersand the http response status code needs to be 200.

因此,您的 API/服务器需要相应地处理这些 OPTIONS 请求,您需要以适当的方式进行响应,access control headers并且 http 响应状态代码需要为200.

The headers should be something like this, adjust them for your needs:

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

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

The max-age header is important, in my case, it wouldn't work without it, I guess the browser needs the info for how long the "access rights" are valid.

max-age 标头很重要,在我的情况下,没有它就无法工作,我猜浏览器需要“访问权限”有效期的信息。

In addition, if you are making e.g. a POSTrequest with application/jsonmime from a different domain you also need to add the previously mentioned allow origin header, so it would look like this:

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

When the pre-flight succeeds and gets all the needed info your actual request will be made.

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

Generally speaking, whatever Access-Controlheaders are requested in the initial or pre-flight request, should be given in the response in order for it to work.

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

There is a good example in the MDN docs here on this link, and you should also check out this SO post

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

回答by Tadej

JavaScript XMLHttpRequestand Fetchfollow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain.

JavaScript XMLHttpRequestFetch遵循同源策略。因此,使用 XMLHttpRequest 或 Fetch 的 Web 应用程序只能向其自己的域发出 HTTP 请求。

Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

来源:https: //developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

You have to send the Access-Control-Allow-Origin: *HTTP header from your server side.

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

If you are using Apache as your HTTP server then you can add it to your Apache configuration file like this:

如果您使用 Apache 作为您的 HTTP 服务器,那么您可以将其添加到您的 Apache 配置文件中,如下所示:

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

Mod_headers is enabled by default in Apache, however, you may want to ensure it's enabled by running:

Mod_headers 在 Apache 中默认启用,但是,您可能希望通过运行来确保它已启用:

 a2enmod headers

回答by freedev

If you're writing a chrome-extension

如果您正在编写chrome 扩展

You have to add in the manifest.jsonthe permissions for your domain(s).

您必须添加manifest.json域的权限。

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

回答by Sunil Kumar

If you are using IIS server by chance. you can set below headers in the HTTP request headers option.

如果您偶然使用 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';

with this all post, get etc., will work fine.

有了这个所有帖子,获取等,将正常工作。

回答by atiruz

In PHP you can add the headers:

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

回答by Teriblus

For python flask server, you can use the flask-cors plugin to enable cross domain requests.

对于python的flask服务器,你可以使用flask-cors插件来开启跨域请求。

See : https://flask-cors.readthedocs.io/en/latest/

请参阅:https: //flask-cors.readthedocs.io/en/latest/

回答by Rohit Parte

To fix cross-origin-requests issues in a Node JS application:

要修复 Node JS 应用程序中的跨域请求问题:

npm i cors

And simply add the lines below to the app.js

只需将下面的行添加到 app.js

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