http跨域时的options请求
来源:
https://blog.csdn.net/qq_36025814/article/details/108023035
***理论参考:(必读)
从前后端的角度分析options预检请求——打破前后端联调的理解障碍
https://cloud.tencent.com/developer/article/2281002
____________________________________________________________________________________________________________________________________________________________________________________
一、前言
- 1、在有很多情况下,当我们在js里面调用一次ajax请求时,在浏览器那边却会查询到
两次请求
。第一次的Request Method参数是OPTIONS
,还有一次就是我们真正的请求,比如get或是post请求方式。 - 2、
OPTIONS
它用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。 - 3、查阅相关的资料之后发现,这是浏览器对复杂跨域请求的一种处理方式,在真正发送请求之前,会先进行一次预请求,就是我们刚刚说到的参数为OPTIONS的第一次请求,他的作用是用于试探性的服务器响应是否正确,即是否能接受真正的请求,如果在
options请求之后获取到的响应是拒绝性质
的,例如500等http状态,那么它就会停止第二次的真正请求的访问
。
二、简介
- 出于安全考虑,并不是所有域名访问后端服务都可以。其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源或者域),还有是否需要Credentials(认证信息)等。那么浏览器在什么情况下能预检呢?
三、两种请求方式
浏览器将CORS请求分为两类:简单请求(
simple request
)和非简单请求(not-simple-request
),简单请求浏览器不会预检,而非简单请求会预检。这两种方式怎么区分?
同时满足下列三大条件
,就属于简单请求,否则属于非简单请求
- 1、请求方式只能是:GET、POST、HEAD
- 2、HTTP请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID
- 3、Content-type只能取:application/x-www-form-urlencoded、multipart/form-data、text/plain
对于简单请求,浏览器直接请求,会在请求头信息中,增加一个origin字段,来说明本次请求来自哪个源(协议+域名+端口)。服务器根据这个值,来决定是否同意该请求,服务器返回的响应会多几个头信息字段,如图所示:上面的头信息中,三个与CORS请求相关,都是以Access-Control-开头。
- 1、Access-Control-Allow-Origin:该字段是必须的,* 表示接受任意域名的请求,还可以指定域名
- 2、Access-Control-Allow-Credentials:该字段可选,是个布尔值,表示是否可以携带cookie,
注意:如果Access-Control-Allow-Origin字段设置*,此字段设为true无效
- 3、Access-Control-Allow-Headers:该字段可选,里面可以获取Cache-Control、Content-Type、Expires等,如果想要拿到其他字段,就可以在这个字段中指定。比如图中指定的GUAZISSO
非简单请求是对那种对服务器有特殊要求的请求,比如请求方式是PUT或者DELETE,或者Content-Type字段类型是application/json。都会在正式通信之前,增加一次HTTP请求,称之为预检。浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中,服务器允许之后,浏览器会发出正式的XMLHttpRequest请求,否则会报错。(备注:之前碰到预检请求后端没有通过,就不会发正式请求,然后找了好久原因,原来后端给忘了设置…)Java后端实现拦截器,排除Options
就Content-Type为application/json为例:对比两张图片,一次预检请求,一 次正式请求:预检请求
正式请求
- 很明显,请求头中预检请求不会携带cookie,正式请求会携带cookie和参数。跟普通请求一样,响应头也会增加同样字段。
- 一旦服务器通过了“预检”请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样。