为什么会有OPTIONS预请求 - CORS跨域
1、问题原因 进行 CORS 跨域时,在有的浏览器中有时会出现:一次动作,两次请求。 这个问题是在进行前后端分离开发时,由于跨域引起的。
在以前,跨域可以使用 代理、JSONP 等方式,在现代浏览器中,我们有更好的选择:CORS。
使用 CORS 跨域,只需要在服务端设置 Access-Control-Allow-Origin 响应头,即可像访问同源接口一样访问跨域接口。
在使用 CORS 跨域时,后台采用 token 检验机制,前台发送请求必须将 token 放到 Request Headers 中,那么就需要传输自定义 Headers 信息,这时候在发送 ajax 请求时,有时一次动作会触发两次请求。一次是 OPTIONS 请求,一次是真正的请求。
下面是这个问题的答案:
对于 CORS 跨域,有两种请求类型
- 简单跨域请求
- 复杂跨域请求(带有 OPTIONS 请求)
2、简单跨域请求 简单跨域请求满足下面两个条件。
- 请求方法是下面三种方法之一
- GET
- POST
- HEAD
- 请求头信息不超过以下几种字段
-
Accept -
Accept-Language -
Content-Language -
Last-Event-ID -
Content-Type(只限于三个值:application/x-www-form-urlencoded、multipart/form-data、text/plain)
简单跨域请求的部分响应头如下:
-
Access-Control-Allow-Origin(必选):不写会请求失败。该项控制数据可见范围,如果想对任何人可见,将其设为 * -
Access-Control-Allow-Credentials(可选):该项控制请求是否包含 cookies 信息。包含设置为 true(必须小写),不包含,请略去该项,而不是填写 false!这一项于 XmlHttpRequest2 对象中的 withCredentials 属性应该保持一致,即 withCredentials 属性设置为 true,则该项也设置为 true;withCredentials 设置为 false,该项要略去不写,不能是 false,如果是 false 会导致请求失败。 -
Access-Control-Expose-Headers(可选):该项确定 XmlHttpRequest2 对象中getResponseHeader方法所能获得的额外信息。通常情况下,getResponseHeader方法能获得如下信息:-
Cache-Control -
Content-Language -
Content-Type -
Expires -
Last-Modified -
Pragma
-
当你需要使用 getResponseHeader 方法获取额外信息时,就需要在这一项中填写并以逗号分隔。
3、复杂的跨域请求 只要不满足上面简单跨域请求条件的请求都是复杂跨域请求。 复杂跨域请求会发送一个预请求(OPTIONS 请求)。只有预请求返回成功时,实际请求才开始执行。
预请求以 OPTIONS 的形式发送,包含域,并且包含两项 CORS 特有的内容:
-
Access-Control-Request-Method请求方法。可以是 GET、POST、PUT、DELETE -
Access-Control-Request-Headers请求头。一个逗号分隔的列表
所以预请求就是提前发送一个 “权限请求”,为后面的实际请求做准备。一旦预请求返回成功,则证明权限满足。
4、解决预请求的办法
后台设置 Access-Control-Max-Age 来控制浏览器在多长时间内(单位 s)不需要发送 OPTIONS 预请求,从而减少不必要的请求。
原文链接: https://juejin.im/post/5c46af87e51d4552232feaeb