justjavac / the-front-end-knowledge-you-may-not-know

:innocent: 你可能不知道的前端知识点
https://git.io/fjrsr
2.28k stars 118 forks source link

Preflighted requests 可以算一个不? #8

Open iamnotblank opened 7 years ago

iamnotblank commented 7 years ago

本人小菜一枚。这个知识点其实蛮基础的,估计在大大们看来肯定很简单。

最近接了一个老项目,配置好跑起来。network面板一看,一大坨空请求,因为要调优,肯定是要去掉的。但诡异的是竟然找不到在哪发的,最后展开method列看看都是options请求。然后查查资料发现还有这玩意,还是蛮惊奇的。附链接

justjavac commented 7 years ago

这个也在计划之中:

如果跨域的请求不是简单请求,就会发送 options 请求。

Tao-Quixote commented 7 years ago

@iamnotblank @justjavac 我也是第一次知道preflighted request,MDN文档规范对COSR要求:

对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

请问:对于 @iamnotblank 遇到这种问题怎么调优呢?对于可能更改服务器数据的请求,可不可以认为“预检请求”属于安全验证范围内的最优,并不需要优化?

justjavac commented 7 years ago

若请求满足所有下述条件,则该请求可视为“简单请求”:

  1. 使用下列方法之一:
    • GET
    • HEAD
    • POST
  2. Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (需要注意额外的限制)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  3. Content-Type 的值属于下列之一:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

其实大部分情况我们发送的都是简单请求。唯一需要注意的就是,如果 Content-Type 是 xml 或者 json,那么这个请求是一个 preflighted request。所以,如果发送 json 时,可以选择 text/plain 格式。