1

根据这里的样本:

如果请求使用 GET、HEAD 或 POST 以外的方法。此外,如果 POST 用于发送 Content-Type 不是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 的请求数据,例如,如果 POST 请求向服务器发送 XML 有效负载使用 application/xml 或 text/xml,然后预检请求。

因此,在以下示例中,由于 XML Content-Type 和自定义标头,执行了预检X-PINGOTHER

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';

function callOtherDomain(){
  if(invocation)
    {
      invocation.open('POST', url, true);
      invocation.setRequestHeader('X-PINGOTHER', 'pingpong'); //<====
      invocation.setRequestHeader('Content-Type', 'application/xml'); //<====
      invocation.onreadystatechange = handler;
      invocation.send(body); 
    }
}

但是在所谓的 pre-flight OPTIONS 请求中(下),只通知服务器 HTTP 方法和自定义 header。没有人告诉服务器关于XML Content-Type.

从逻辑上讲,只要发送了预检请求,就意味着Content -Type不是不需要预检的 3 种形式。但是还有许多其他的可能性。底线是,服务器应该能够知道为什么发送预检请求。

那么服务器如何合理地决定是否允许这个缺少拼图(内容类型)的请求呢?

在此处输入图像描述

4

1 回答 1

3

CORS几乎总是安全的。引用Fetch Standard

对于通过 IP 身份验证或防火墙保护数据的资源(不幸的是,仍然比较常见),使用 CORS 协议是不安全的。(这就是必须发明 CORS 协议的原因。)

但是,否则使用以下标头是安全的:

访问控制允许来源:*

即使资源暴露了基于 cookie 或 HTTP 身份验证的附加信息,使用上述标头也不会泄露它。它将与 XMLHttpRequest 等 API 共享资源,就像它已经与 curl 和 wget 共享一样。

因此,换句话说,如果无法从使用 curl 和 wget 连接到网络的随机设备访问资源,则不包含上述标头。但是,如果可以访问它,那么这样做是完全可以的。

因此,服务器不需要知道关于请求的内容类型的任何信息,就可以知道如何响应 OPTIONS 请求。服务器只需要知道:被询问的 URL 是只能通过基于 IP 的身份验证访问,还是在某些防火墙或 Intranet 后面?如果是,那么它应该拒绝 OPTIONS 请求。如果不是,即如果可以使用 curl、wget、telnet 或您喜欢的 HTTP 库等工具通过公共 Internet 访问资源,那么它应该允许 OPTIONS 请求。这样做只会为浏览器提供与其他工具相同的访问权限。

然后,当后续 POST 请求进来时,服务器可以做出进一步的决定。例如,服务器可能想要拒绝 Content-Type 错误的 POST。但它总是想这样做。它不想只拒绝来自尊重 CORS 的浏览器的 OPTIONS 请求;相反,它应该拒绝来自任何来源的 POST 请求。

(浏览器特别的原因如下。考虑一个遵循不良安全实践的内部网,任何 IP 地址在一定范围内的人都可以读取,即任何使用公司计算机的人。通常,这没问题:内部的人使用 curl 的公司可以访问数据,而外部使用 curl 的人不能。但是,考虑一下公司内部有人浏览了某个恶意网站https://evil.com/。如果 evil.com 使用 XHR API访问http://intranet/secret-data,则请求将来自特权 IP 地址,因为它是特权用户计算机上的浏览器执行请求。为了防止这种安全漏洞,CORS 协议被发明出来,这样浏览器就不会直接 ​​POST 到http://intranet/secret-data,而是首先发出一个 OPTIONS 请求,整个http:// Intranet可能只会说“不,你不能访问这个”,然后 POST 永远不会发生。)

于 2016-01-08T02:56:32.903 回答