怎样避免跨域发出OPTIONS请求?
前言
我们在做移动开发的时候,往往在服务器中加入Access-Control-Allow-Origin,用来跨域,虽然这是最简单的跨域方案了,但是有一个问题,就是每一次正式请求的前面总是会带上一次OPTIONS请求,一些程序员往往一头雾水。
imageimage.png
原因
浏览器在处理跨域请求之前,会先对跨域请求做一个分析,将跨域请求分为2种:简单请求,和非简单请求。
具备以下特征的是简单请求:
-
请求方式只能是:GET、POST、HEAD
-
HTTP请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID
-
Content-type只能取:application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是超出这些限制的请求一律被浏览器视为复杂请求,如果想跨域,浏览器会发送一个OPTIONS请求,跟服务器一探究竟。
如果服务器返回的数据让浏览器很满意,那么浏览器才会发出正式请求。
怎样避免OPTIONS请求?
因为OPTIONS请求也是占带宽和时间的,从上图也可以看到,每个请求都带一个OPTIONS,非常难受。怎么避免?
改默认请求类型
axios的默认请求内容类型是application/json,这就倒霉催的了,只能是修改成application/x-www-form-urlencoded。相应的,post数据的时候,要用qs库。具体做法去搜索吧。
还是不行,咋回事?
你肯定是往headers里放东西了。别放就行了。
有人说了,我token就喜欢放在headers里,怎么办?
这下子前端是没有好办法了,只能从后端想办法了,就是使用Access-Control-Max-Age。
这需要后端同学配合,在设置OPTIONS跨域响应headers的时候,添加 Access-Control-Max-Age ,这个参数的意思是把 OPTIONS 响应缓存起来,在指定的时间内,不会再次发起 OPTIONS 预请求,这样只有在第一次请求的时候会有 OPTIONS ,之后浏览器会从缓存里读取响应,也就不会再发送OPTIONS请求了。比如:
// 后端设置,2592000,单位秒,也就是30天,如果是一天,就是86400
response.addHeader( "Access-Control-Max-Age", "2592000" )
注意,后端只需要处理OPTIONS请求,不要改正常的GET、POST请求。