浏览器中的preflight请求-预检请求

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器中的preflight请求-预检请求相关的知识,希望对你有一定的参考价值。

参考技术A

preflight,一个cors预检请求,属于options请求。该请求会在浏览器认为即将要执行的请求可能会对服务器造成不可预知的影响时,由浏览器 自动 发出。
利用预检请求,浏览器能够知道当前的服务器是否允许执行即将要进行的请求,只有获得了允许,浏览器才会真正执行接下来的请求。
所以,总结有几点:

preflight预检请求属于cors规范的一部分,是一种服务器验证机制。目前所有浏览器都实现了该规范,但是不免有些浏览器会对规范内容进行扩充。但是必须实现的规范是:只有以下条件 满足的情况下才不会发送预检请求,否则会在发送用户请求之前发送预检请求,以免在获得允许之前对服务器产生不可预知的影响。
条件有:

只能使用GET、POST方法

只能包含九种请求头:

只能包含三种类型:

该对象没有注册任何事件监听器

请求中不能使用ReadableStream对象

如果以上条件有一条不满足,浏览器则会自动发起预检请求

浏览器自动发送的预检请求,一般采用三个字段来表示:

服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。

所以服务器同时需要配置preflight响应来回应浏览器,告知浏览器是否接受预检请求,主要涉及到三个字段:

举一个例子:

客户端自定义了一个请求头uname,内容是admin。但是此时服务器端并没有预检请求的处理(这里使用node作为服务器端)

客户端:

服务器(由于是不同域,所以实现处理了跨域请求):

结果:

可以看到在发送用户请求 http://127.0.0.1:8000/server 之前,浏览器先发送了一个预检请求,Type=preflight,而触发预检请求的原因是:客户端在请求头中添加了自定义请求头。但是由于服务器端没有预检请求的处理,所以浏览器没有得到预检请求的响应,就不会处理用户本身要发送的请求,因此可以看到/server这个请求出现了 CORS ERROR

按照之前所理解的预检请求,我们可以在服务器端进行配置对该请求的响应:

注意:由于preflight请求属于cors规范的一部分,因此当前仅当跨域的情况下可能会触发preflight。也即:只有跨域了,且不满足之前触发条件中一条就会触发预检请求。没有跨域,不会触发预检请求。

以上是关于浏览器中的preflight请求-预检请求的主要内容,如果未能解决你的问题,请参考以下文章

CORS Preflight 请求是不是包含请求的标头?

如何在浏览器中实际缓存CORS预检响应?

将正确的标头值发送到从角度 $http 到 asp.net webapi 的 Preflight 请求时出错

CORS预检请求详谈

为啥 Postman 和 Fiddler 从不生成预检请求

[CORS][Spring Security] PreFlight 请求未处理