Javascript CORS - 如何“预检”httprequest?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8685678/
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
CORS - How do 'preflight' an httprequest?
提问by Nick
I am trying to make a cross domain HTTP request to WCF service (that I own). I have read several techniques for working with the cross domain scripting limitations. Because my service must accommodate both GET and POST requests I cannot implement some dynamic script tag whose src is the URL of a GET request. Since I am free to make changes at the server I have begun to try to implement a workaround that involves configuring the server responses to include the "Access-Control-Allow-Origin" header and 'preflight' requests with and OPTIONS request. I got the idea from this post : Getting CORS working
我正在尝试向 WCF 服务(我拥有)发出跨域 HTTP 请求。我已经阅读了几种处理跨域脚本限制的技术。因为我的服务必须同时容纳 GET 和 POST 请求,所以我无法实现一些动态脚本标记,其 src 是 GET 请求的 URL。由于我可以自由地在服务器上进行更改,因此我已开始尝试实施一种解决方法,该解决方法涉及配置服务器响应以包含“Access-Control-Allow-Origin”标头和带有 OPTIONS 请求的“预检”请求。我从这篇文章中得到了想法:让 CORS 工作
At the server side, my web method is adding 'Access-Control-Allow-Origin: *' to the HTTP response. I can see that responses do include this header now. My question is: How do I 'preflight' a request (OPTIONS)? I am using jQuery.getJSON to make the GET request but the browser cancels the request right away with the infamous:
在服务器端,我的 Web 方法正在向 HTTP 响应添加“Access-Control-Allow-Origin: *”。我可以看到响应现在确实包含此标头。我的问题是:如何“预检”请求(选项)?我正在使用 jQuery.getJSON 发出 GET 请求,但浏览器立即取消了该请求,并出现了臭名昭著的:
Origin http://localhostis not allowed by Access-Control-Allow-Origin
Access-Control-Allow-Origin 不允许Origin http://localhost
Is anyone familiar with this CORS technique? What changes need to be made at the client to preflight my request?
有人熟悉这种 CORS 技术吗?需要在客户端进行哪些更改以预检我的请求?
Thanks!
谢谢!
回答by monsur
During the preflight request, you should see the following two headers: Access-Control-Request-Method and Access-Control-Request-Headers. These request headers are asking the server for permissions to make the actual request. Your preflight response needs to acknowledge these headers in order for the actual request to work.
在预检请求期间,您应该看到以下两个标头:Access-Control-Request-Method 和 Access-Control-Request-Headers。这些请求标头要求服务器授予发出实际请求的权限。您的预检响应需要确认这些标头才能使实际请求工作。
For example, suppose the browser makes a request with the following headers:
例如,假设浏览器使用以下标头发出请求:
Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header
Your server should then respond with the following headers:
然后,您的服务器应使用以下标头进行响应:
Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header
Pay special attention to the Access-Control-Allow-Headers response header. The value of this header should be the same headers in the Access-Control-Request-Headers request header, and it can not be '*'.
请特别注意 Access-Control-Allow-Headers 响应标头。这个header的值应该和Access-Control-Request-Headers请求头中的headers一样,不能是'*'。
Once you send this response to the preflight request, the browser will make the actual request. You can learn more about CORS here: http://www.html5rocks.com/en/tutorials/cors/
一旦您将此响应发送到预检请求,浏览器将发出实际请求。您可以在此处了解有关 CORS 的更多信息:http://www.html5rocks.com/en/tutorials/cors/
回答by Fabien Haddadi
Although this thread dates back to 2014, the issue can still be current to many of us. Here is how I dealt with it in a jQuery 1.12 /PHP 5.6 context:
尽管这个话题可以追溯到 2014 年,但这个问题对我们中的许多人来说仍然是最新的。这是我在 jQuery 1.12 /PHP 5.6 上下文中处理它的方法:
- jQuery sent its XHR request using only limited headers; only 'Origin' was sent.
- No preflight request was needed.
- The server only had to detect such a request, and add the "Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN'] header, after detecting that this was a cross-origin XHR.
- jQuery 仅使用有限的标头发送其 XHR 请求;只发送了“Origin”。
- 不需要预检请求。
- 服务器只需要检测这样的请求,并添加“Access-Control-Allow-Origin:”。$_SERVER['HTTP_ORIGIN'] 标头,在检测到这是一个跨域 XHR 之后。
PHP Code sample:
PHP 代码示例:
if (!empty($_SERVER['HTTP_ORIGIN'])) {
// Uh oh, this XHR comes from outer space...
// Use this opportunity to filter out referers that shouldn't be allowed to see this request
if (!preg_match('@\.partner\.domain\.net$@'))
die("End of the road if you're not my business partner.");
// otherwise oblige
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
// local request, no need to send a specific header for CORS
}
In particular, don't add an exit;
as no preflight is needed.
特别是,不要添加 ,exit;
因为不需要预检。