CORS:为什么我的浏览器没有发送OPTIONS飞行前请求? [英] CORS: Why my browser doesn't send OPTIONS preflight request?

查看:852
本文介绍了CORS:为什么我的浏览器没有发送OPTIONS飞行前请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我对 CORS 的了解,我知道它应该按以下方式工作:

From what I've read about CORS, I understand it should work as follows:

    客户端上的
  1. 脚本会尝试从具有不同起源的服务器中获取资源.
  2. 浏览器拦截此请求,并首先向同一URL发出 preflight OPTIONS请求.
  3. 如果对此预检请求的响应包含适当的标头(例如Access-Control-Allow-Origin: *),则浏览器会理解并允许发送主请求.
  4. 响应将返回到客户端脚本.
  1. Script on a client side tries to fetch a resource from a server with different origin.
  2. Browser intercepts this request and first makes preflight OPTIONS request to the same URL.
  3. If response to this preflight request contains appropriate headers (e.g. Access-Control-Allow-Origin: *), browser understands it's allowed to send main request and does it.
  4. Response is returned to the client script.

我已经为此设置了一个测试:

I've set up a test for it like this:

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

  • server in Go accepting both - GET and OPTIONS requests (checked using CURL) - and setting Access-Control-* headers in response
  • simple HTML page (served by another server on another port) with the following script in it ($ stands for 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且没有预检OPTIONS请求.

When I call this method, however, I see only one GET and no preflight OPTIONS request in the Network tab in both - Chrome 49 and Firefox 33.

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

Here are details of my GET request from 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

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

Any thoughts on why my browser(s) don't send preflight request?

推荐答案

正如评论员所指出的那样,使用GET 浏览器并不总是发送预检选项请求.如果确实需要进行飞行前检查,则使浏览器进行发送的一种方法是设置自定义标头(例如"X-PINGOVER:乒乓"或其他内容).请注意,该服务器还应通过将此 request标头添加到"Access-Control-Allow-Headers" 响应标头中.

As pointed out by commentators, with GET browser doesn't always send preflight OPTIONS request. If preflight is indeed needed, one way to make browser to send it is to set custom header (e.g. "X-PINGOVER: pingpong" or whatever). Note, that server should also allow this request header by adding it to "Access-Control-Allow-Headers" response header.

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

My underlying goal was to pass cookies with domain a.com to servers of a.com, but from a page of another site(s) b.com (common use case for this is tracking your users on 3rd party websites). It turns out to send cookies alongside the request a bit more work is involved.

客户端(即JavaScript)中,需要启用跨域请求并允许传递凭据.例如. jQuery的以下请求对我有效:

On the client side (i.e. in JavaScript) one needs to enable cross domain request and allow passing credentials. E.g. the following request with jQuery worked for me:

$.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个响应标头:

On the server side one needs to set 2 response headers:

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

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

where <requester origin> is protocol + host + port of a website that performed a call. Note, that generic * may not work in many browsers, so it makes sense for server to parse Referer header of request and respond with specific allowed origin.

这篇关于CORS:为什么我的浏览器没有发送OPTIONS飞行前请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆