CORS - 如何“预检”httprequest?

2022-08-30 05:34:28

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

在服务器端,我的Web方法正在将“访问控制-允许-源:*”添加到HTTP响应中。我可以看到响应现在确实包含此标头。我的问题是:如何“预检”请求 (OPTIONS)?我正在使用jQuery.getJSON发出GET请求,但浏览器立即取消了臭名昭着的请求:

访问控制-允许-源不允许源 http://localhost

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

谢谢!


答案 1

在预检请求期间,您应看到以下两个标头:访问控制请求方法和访问控制请求标头。这些请求标头要求服务器提供发出实际请求的权限。您的印前检查响应需要确认这些标头,以使实际请求正常工作。

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

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

请特别注意访问控制允许标头响应标头。此标头的值应与访问控制请求标头中的标头相同,并且不能为“*”。

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


答案 2

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

  • jQuery仅使用有限的标头发送其XHR请求;只发送了“起源”。
  • 不需要预检请求。
  • 服务器只需要检测这样的请求,并添加“访问控制-允许-源:”。$_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;