CORS - 如何“预检”httprequest?

时间:2011-12-31 01:36:06

标签: javascript wcf jquery cors

我正在尝试向WCF服务(我拥有)进行跨域HTTP请求。我已经阅读了几种处理跨域脚本限制的技术。因为我的服务必须同时兼顾GET和POST请求,所以我无法实现一些动态脚本标记,其src是GET请求的URL。由于我可以自由地在服务器上进行更改,因此我开始尝试实施一种解决方法,该方法涉及配置服务器响应以包括“Access-Control-Allow-Origin”标头和带有OPTIONS请求的“预检”请求。我从这篇文章中得到了这个想法:Getting CORS working

在服务器端,我的web方法是在HTTP响应中添加“Access-Control-Allow-Origin:*”。我现在可以看到响应包含此标题。我的问题是:我如何“预检”一个请求(OPTIONS)?我正在使用jQuery.getJSON来发出GET请求,但是浏览器会立即取消臭名昭着的请求:

  

Access-Control-Allow-Origin

不允许原点http://localhost

有人熟悉这种CORS技术吗?需要在客户端进行哪些更改以预检我的请求?

谢谢!

2 个答案:

答案 0 :(得分:145)

在预检请求期间,您应该看到以下两个标题:Access-Control-Request-Method和Access-Control-Request-Headers。这些请求标头要求服务器发出实际请求的权限。您的预检响应需要确认这些标题,以便实际请求起作用。

例如,假设浏览器使用以下标头发出请求:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

然后,您的服务器应使用以下标头进行响应:

Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

请特别注意Access-Control-Allow-Headers响应标头。此标头的值应与Access-Control-Request-Headers请求标头中的标头相同,并且不能为“*”。

将此响应发送到预检请求后,浏览器将发出实际请求。您可以在此处了解有关CORS的更多信息:http://www.html5rocks.com/en/tutorials/cors/

答案 1 :(得分:0)

虽然这个帖子可以追溯到2014年,但这个问题对我们许多人来说仍然是最新的。以下是我在jQuery 1.12 / PHP 5.6上下文中处理它的方法:

  • jQuery仅使用有限的标头发送其XHR请求;只发送了'Origin'。
  • 无需预检请求。
  • 服务器只需检测此类请求,并添加“Access-Control-Allow-Origin:”。 $ _SERVER ['HTTP_ORIGIN']标题,在检测到这是一个跨源XHR之后。

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
}

特别是,不要添加exit;,因为不需要预检。