Javascript CORS:为什么我的浏览器没有';发送选项飞行前请求?

Javascript CORS:为什么我的浏览器没有';发送选项飞行前请求?,javascript,jquery,cors,Javascript,Jquery,Cors,从我所读到的内容来看,我理解它的工作原理如下: 客户端上的脚本尝试从具有不同来源的服务器上获取资源 浏览器截取此请求并首先向同一URL发出飞行前选项请求 如果对该飞行前请求的响应包含适当的头文件(例如访问控制允许源文件:),则浏览器理解允许发送主请求并执行此操作 响应返回到客户端脚本 我为它设置了一个测试,如下所示: Go中的服务器同时接受-GET和OPTIONS请求(使用CURL进行检查),并在响应中设置Access Control-*headers 简单HTML页面(由另一个端口上的另一台

从我所读到的内容来看,我理解它的工作原理如下:

  • 客户端上的脚本尝试从具有不同来源的服务器上获取资源
  • 浏览器截取此请求并首先向同一URL发出飞行前选项请求
  • 如果对该飞行前请求的响应包含适当的头文件(例如
    访问控制允许源文件:
    ),则浏览器理解允许发送主请求并执行此操作
  • 响应返回到客户端脚本 我为它设置了一个测试,如下所示:

    • Go中的服务器同时接受-GET和OPTIONS请求(使用CURL进行检查),并在响应中设置
      Access Control-*
      headers
    • 简单HTML页面(由另一个端口上的另一台服务器提供),其中包含以下脚本(
      $
      代表jQuery):

    然而,当我调用这个方法时,我在Chrome 49和Firefox 33的网络选项卡中只看到一个GET和no飞行前选项请求

    以下是我从Chrome获取请求的详细信息:

    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
    

    关于我的浏览器为什么不发送飞行前请求有什么想法吗

    正如评论员所指出的,使用GET浏览器并不总是发送飞行前选项请求。如果确实需要飞行前准备,让浏览器发送的一种方法是设置自定义标题(例如“X-PINGOVER:pingpong”或其他内容)。注意,服务器还应该通过将该请求头添加到“Access Control allow Headers”响应头来允许该请求头


    我的基本目标是通过域
    a.com
    cookies传递给
    a.com
    的服务器,但要从另一个站点
    b.com
    的页面传递(这方面的常见用例是在第三方网站上跟踪您的用户)。事实证明,在请求的同时发送cookie需要做更多的工作

    在客户端(即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个响应头:

    • 访问控制允许凭据:true
    • 访问控制允许原点:

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

    飞行前准备并不总是完成的,不太可能(如果有的话?)使用GET-see来了解何时需要飞行前准备。有关浏览器何时发出飞行前请求的详细信息,请参阅。@JaromandaX:谢谢您的评论。如果不总是需要飞行前请求,那么克服“同源”政策的(常规)方法是什么?场景是:我们创建了一个脚本,该脚本将被整合到第三方网站中,并向我们发送cookie?据我所知,如果没有飞行前请求,浏览器将不会向我们的服务器发送cookie,对吗?请参阅我链接的文档中的下一节-我建议阅读整个页面-这是informativeSee文档以获取更多信息。需要注意的是,您的服务器可能不希望“X-PINGOVER”作为标题,并且可能返回错误。要解决此问题,请在服务器代码中设置
    Access Control Allow Headers
    的值,包括
    X-PINGOVER
    $.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) { ... }
    });