为什么跨源HEAD请求需要进行预检检查?

时间:2014-02-28 23:23:10

标签: cross-domain cors http-method preflight

我正在阅读有关CORS请求的spec,我发现了有关预检请求的信息:

  

这些是对具有HTTP请求的非同一原始URL的请求   首先需要使用a来授权的GET以外的方法   预检结果缓存条目或预检请求。

我原以为预检请求的目的是在创建请求之前检查是否允许请求,以防万一(非法)更改服务器状态

但是HEAD和OPTIONS不会修改服务器状态。我必须误解飞行前检查的原因。

对HEAD和OPTIONS进行预检检查但不是GET的目的(也就是原因,动机或理由)是什么? GET有什么特别之处?

1 个答案:

答案 0 :(得分:18)

预检的主要目的是确保服务器不会突然发送基于浏览器的跨域请求,这些请求在实施CORS规范之前可能从未收到过。

在CORS规范之前,除了GET或POST之外,不可能发送任何基于浏览器的跨源请求。浏览器根本不允许您启动XHR实例,将方法设置为PUT(例如)并将其发送到不同来源的端点。您无法通过XHR发送GET或POST跨源请求,但您可以通过表单提交发送跨源GET或POST,或通过<img>或{{1}发送跨源GET例如,标签(使得JSONP成为CORS之前的唯一选项)。一旦浏览器实现了CORS规范,这就改变了。现在,只要服务器选择,就可以发送任何跨源的ajax请求。

CORS规范定义了“简单”方法(GET和POST)以及“简单”请求标头。这些对应于您可能已经从浏览器之前的CORS规范发送的跨源请求的类型。非简单的跨源请求,例如带有X-header的PUT或POST / GET请求(例如)无法从CORS之前的浏览器发送。因此,对于这些类型的请求,预检的概念被写入规范中,以确保服务器不会在没有明确选择的情况下接收这些类型的非简单的跨源浏览器请求。换句话说,如果不这样做想要允许这些类型的请求,您根本不必更改服务器。预检将失败,浏览器将永远不会发送基础请求。

直接解决您的问题:HEAD请求通常不会导致预检。根据CORS规范,HEAD被认为是一种简单的请求方法。如您所知,HEAD请求只是没有响应有效负载的GET。这是HEAD和GET请求被视为相同的最可能原因,即使您无法从浏览器发送CORS前的跨源HEAD请求。如果您的HEAD包含非简单标题,那么它将被预检,就像GET一样。