axios 跨域请求详解
栏目: JavaScript · 发布时间: 5年前
内容简介:写这篇文章的背景是因为之前遇到的,在跨域的情况下通过 axios 发起的 get 请求正常,post 请求会在正式请求发送之前先发送一个 opstions 请求,而后端接口没有兼容 options,导致 404 的情况。而在解决这个问题时带着好奇心顺带查了一下,给自己补充了些知识点。简单讲,从
写这篇文章的背景是因为之前遇到的,在跨域的情况下通过 axios 发起的 get 请求正常,post 请求会在正式请求发送之前先发送一个 opstions 请求,而后端接口没有兼容 options,导致 404 的情况。
而在解决这个问题时带着好奇心顺带查了一下,给自己补充了些知识点。
跨域请求分两种
简单讲,从 JavaScript
代码发起的 XMLHttpRequest
请求可以分为两种:
简单请求:
不会触发 CORS预检
的请求,而是直接向服务端发送请求,什么是 CORS预检
咱们后面说,其匹配的规则大致如下:
-
请求方法为
GET
、HEAD
、POST
中的一种 -
CORS安全部首字段在以下集合中:
ACCEPT Accept-Language Content-Language DPR Downlink Save-Data Viewport-Width Width Content-Type (值仅限text/plain,multipart/form-data,application/x-www-form-urlencoded)
-
请求中的
XMLHttpRequestUpload
对象没有注册任何事件监听 -
请求中没有
ReadableStream
对象
预检请求:
在发送正式请求之前,会先发起一个 OPTIONS
预检请求到服务器,以获知服务器是否允许该实际请求,若不允许,则不再发送请求,其匹配规则如下:
-
请求方法为:
PUT
、DELETE
、CONNECT
、OPTIONS
、TRACE
、PATCH
之一 -
人为设置了
CORS安全部首字段集合
之外的字段 -
请求中的
XMLHttpRequestUpload
对象注册了任意事件监听器 -
请求中使用了
ReadableStream
对象
在跨域请求中,若服务端返回了正确的跨域响应部首: Access-Control-Allow-Origin
、 Access-Control-Allow-Method
、 Access-Control-Allow-Headers
, 则跨域请求能正常获取数据。
问题解决
根据以上了解的知识点,跟进遇到的问题,发现 axios 的请求部首 Content-Type
的值默认为 application/json;charset=utf-8
,且 POST
请求数据为 json
格式,故进行 POST
请求会先发出预检请求,若服务端对预检请求的响应为不支持,则请求终止。
根据上面分析出的原因,以下列举两种解决方案:
完善服务端接口及跨域响应部首
使服务端接口支持 OPTIONS
方法,且对跨域预检请求的请求部首进行完整的响应匹配,表明服务器将接受后续的实际请求,则实际请求将被正常响应。
前端侧处理 axios 的 POST 请求数据
跨域时将请求转换为简单请求:
-
请求部首的
Content-Type
设为application/x-www-form-urlencoded
-
处理
POST
请求数据,方式有以下两种:-
通过
URLSearchParams
生成POST
请求的数据 -
使用
qs
库的stringify
api 对请求数据进行转换( 若请求数据中某个字段的值为引用类型,需要先通过 JSON.stringify 处理,以防止服务端无法识别 )
-
通过
例子:
/* 通过 qs 模块处理请求数据*/ import axios from 'axios' import qs from 'qs' axios.defaults.withCredentials = true // 若跨域请求需要带 cookie 身份识别 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded' // 请求拦截器 axios.interceptors.request.use(req => { // 对 post 请求数据进行处理 if (req.method === 'post') { Object.keys(req.data).forEach(item => { !isPrimeval(req.data[item]) && (req.data[item] = JSON.stringify(req.data[item])) }) req.data = qs.stringify(req.data) } return req }, error => { // 请求出错时处理 return Promise.reject(error) }) or /* 通过 URLSearchParams 生成 POST 请求数据 */ import axios from 'axios' async function anInterface (url, params = {}) { let data = new URLSearchParams() for(let key in params) { data.append(params[key]) } const res = await axios.post(url, data) // 处理数据 return res.data } 复制代码
通过以上方式即可将 POST
预检请求转换为简单请求,其好处不言而喻,对于多个 POST
请求而言,可以减少一半的请求数量,且在一些服务端比较不能改动的场景更为适用。
以上为本次文章所有内容,若有问题,望指正;若需转载,望注明出处
以上所述就是小编给大家介绍的《axios 跨域请求详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 详解nginx的请求限制(连接限制和请求限制)
- 详解用 Go 语言解析各种 HTTP 请求的方法
- Springboot -- 用更优雅的方式发HTTP请求(RestTemplate详解)
- angular请求防抖,以及处理第一次请求失效
- RxHttp 一条链发送请求,新一代Http请求神器(一)
- RxHttp 一条链发送请求,新一代Http请求神器(一)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Algorithms to Live By
Brian Christian、Tom Griffiths / Henry Holt and Co. / 2016-4-19 / USD 30.00
A fascinating exploration of how insights from computer algorithms can be applied to our everyday lives, helping to solve common decision-making problems and illuminate the workings of the human mind ......一起来看看 《Algorithms to Live By》 这本书的介绍吧!