CORS:为什么我的浏览器不;t发送OPTIONS飞行前请求

CORS: Why my browser doesn't send OPTIONS preflight request?

本文关键字:发送 OPTIONS 飞行前 请求 为什么 我的 浏览器 CORS      更新时间:2023-09-26

从我读到的关于CORS的内容来看,我理解它应该如下工作:

  1. 客户端上的脚本试图从具有不同来源的服务器获取资源
  2. 浏览器拦截此请求,并首先向同一URL发出preflight OPTIONS请求
  3. 如果对该飞行前请求的响应包含适当的头(例如Access-Control-Allow-Origin: *),则浏览器理解允许发送主请求并执行该操作
  4. 响应返回到客户端脚本

我为它设置了一个这样的测试:

  • Go中的服务器接受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);
      }
    });
    

然而,当我调用这个方法时,在Chrome 49和Firefox 33的"网络"选项卡中,我只看到一个GET请求,而没有preflight OPTIONS请求。

以下是我从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.comcookie传递到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个响应标头:

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

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