您好,登录后才能下订单哦!
今天小编给大家分享一下options预检请求的前后端解决方法是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
这件事还要从浏览器说起,基本上我们的请求都是CORS跨域请求(前后端分离嘛,基本上部署位置的IP\端口\协议不可能完全相同,所以就属于跨域了),CORS跨域请求需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
而CORS跨域请求,又分成简单请求simple request, 和复杂请求not-so-simple request。
复杂请求就会触发我们的options预检请求,这是符合以下规范的。
跨域共享标准规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法
(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),
浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),
从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。
(1)请求方式为`GET、HEAD、POST`时的请求;
(2)认为设置规范集合之内的首部字段,
如`
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`;
(4)请求中的任意 `XMLHttpRequestUpload`对象均没有注册任何事件监听器;
(5)请求中没有使用 `ReadableStream`对象。
除了上面的以外的请求,基本上都是复杂请求。
比如自定义的token、Authorization等请求头字段,或者是PUT、DELETE等请求方式。
因为预检,会额外占用服务器资源,还会延迟真正请求的发起时间,导致页面上性能变差(这一点在使用openai的api深有体会,因为是国外服务器,加上预检,基本上每次都要返回好久)。
解决方式可以从前端或者后端入手,选其一就可以了,除了以下方法,可能还有其他的解决方式。
// 引入 import qs from 'qs' // 然后在请求拦截器的部分 axios.interceptors.request.use((config) => { if(config.method === 'post'){ config.data = qs.stringify(config.data); } return config; },(error) =>{ return Promise.reject(error); });
如下,从json格式变成了string字符串,后端获取后需要重新格式化一下才能用。
// qs.stringify 前 config.data = { "userId": "520b0ec3229", "startTime": "15489504", "endTime": "1559999" } // qs.stringify 后,内容变为 "userId=520b0ec3229&startTime=15489504&endTime=1559999"
服务器端设置 Access-Control-Max-Age 字段,浏览器会根据返回的
Access-Control-Max-Age 字段缓存该请求的 OPTIONS 预检请求的响应结果。
设置大点就可以了
比如设置30天,那就触发一次预检后,后续30天内,同一请求源头不会再次触发预检请求。
// 后端设置,2592000单位秒,这里是30天 response.addHeader( "Access-Control-Max-Age", "2592000" )
access-control-allow-origin: *;
这种比较危险,因为允许了所有网站都可以跨域共享资源。
可以把*改为具体的网址源,也就是白名单。
以上就是“options预检请求的前后端解决方法是什么”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。