CORS:为什么我的浏览器不发送OPTIONS预检请求?

问题描述:

从我读过有关CORS,我的理解它应该工作如下:CORS:为什么我的浏览器不发送OPTIONS预检请求?

  1. 脚本在客户端试图从服务器不同产地获取资源
  2. 浏览器拦截此请求,并首先将预检选项请求设置为相同的URL。
  3. 如果响应该预检请求包含适当的报头(例如Access-Control-Allow-Origin: *),浏览器理解它允许发送主请求和做它。
  4. 响应返回给客户端脚本。

我已经建立了一个测试这样的:

  • 服务器转到同时接受 - GET和OPTIONS请求(使用curl检查) - 和响应
  • 设置 Access-Control-*
  • 简单的HTML页面下面的脚本在它(jQuery的$站)(由另一个端口上的另一个服务器提供):

    $.ajax({ 
        type: "GET", 
        crossDomain: true, 
        url: "http://local.site.com/endpoint, 
        success: function (data) { 
        alert(data); 
        }, 
        error: function (request, error) { 
        alert(error); 
        } 
    }); 
    

当我把这种方法,但是,我只看到一个GET没有预检选项在网络选项卡要求在两个 - 铬49和Firefox 33

下面是Chrome浏览器使用GET请求的细节:

Accept:*/* 
Accept-Encoding:gzip, deflate, sdch 
Accept-Language:en-US,en;q=0.8,ru;q=0.6 
Connection:keep-alive 
Host:local.adform.com 
Origin:http://localhost:7500 
Referer:http://localhost:7500/test-page.html 
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36 

和相应的响应:

Access-Control-Allow-Headers:Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization 
Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE 
Access-Control-Allow-Origin:* 
Content-Length:2 
Content-Type:text/plain; charset=utf-8 
Date:Wed, 03 Aug 2016 10:53:19 GMT 

任何思考为什么我的浏览器(S)不送预检要求

+2

预检并不总是完成,使用GET的可能性较小(如果有的话) - 请参阅[文档](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests)当需要预检时 –

+1

请参阅[本](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests)以获取有关浏览器何时发出预检请求的更多信息。 – robertklep

+0

@JaromandaX:谢谢你的评论。如果不需要预检请求,那么克服“同源”策略的(传统)方法是什么?情景是:我们创建了一个脚本,将合并到第三方网站,并将发送给我们_our_ cookies?据我所知,没有预检请求,浏览器不会向我们的服务器发送cookies,对吧? – ffriend

正如评论员指出的,使用GET 浏览器并不总是发送预检选项请求。如果确实需要预检,一种使浏览器发送它的方法是设置自定义标题(例如“X-PINGOVER:pingpong”或其他)。请注意,该服务器还应该允许将此请求标头添加到“访问控制允许标头”响应标头


我的基本目标是通过饼干与域a.coma.com服务器,而是从其他网站(S)b.com(常见的用例,这是跟踪用户在第三方网站)的页面。事实证明,与请求一起发送的cookies还有一些工作涉及到。

客户端(即在JavaScript中)需要启用跨域请求并允许传递证书。例如。与jQuery下列要求为我工作:

$.ajax({ 
    type: "GET", 
    url: "http://example.com", 
    xhrFields: { 
    withCredentials: true   // allow passing cookies 
    }, 
    crossDomain: true,    // force corss-domain request     
    success: function (data) { ... }, 
    error: function (request, error) { ... } 
}); 

服务器端一个需要设置2响应头:

  • Access-Control-Allow-Credentials: true
  • Access-Control-Allow-Origin: <requester origin>

其中<requester origin>是协议+主机+执行呼叫的网站的端口。请注意,通用*可能无法在许多浏览器中使用,因此服务器解析请求的标头Referer并使用特定的允许来源进行响应是有意义的。

+0

有关更多信息,请参阅[MDN预检请求](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests)文档。 – styfle

+0

请务必注意,您的服务器可能不期望“X-PINGOVER”作为标题,并且可能会返回错误。为了解决这个问题,在你设置'Access-Control-Allow-Headers'值的服务器代码中,包含'X-PINGOVER' – user2023861