axios 跨域请求详解

栏目: JavaScript · 发布时间: 5年前

内容简介:写这篇文章的背景是因为之前遇到的,在跨域的情况下通过 axios 发起的 get 请求正常,post 请求会在正式请求发送之前先发送一个 opstions 请求,而后端接口没有兼容 options,导致 404 的情况。而在解决这个问题时带着好奇心顺带查了一下,给自己补充了些知识点。简单讲,从

写这篇文章的背景是因为之前遇到的,在跨域的情况下通过 axios 发起的 get 请求正常,post 请求会在正式请求发送之前先发送一个 opstions 请求,而后端接口没有兼容 options,导致 404 的情况。

而在解决这个问题时带着好奇心顺带查了一下,给自己补充了些知识点。

跨域请求分两种

简单讲,从 JavaScript 代码发起的 XMLHttpRequest 请求可以分为两种:

简单请求:

不会触发 CORS预检 的请求,而是直接向服务端发送请求,什么是 CORS预检 咱们后面说,其匹配的规则大致如下:

  1. 请求方法为 GETHEADPOST 中的一种
  2. 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)
    
  3. 请求中的 XMLHttpRequestUpload 对象没有注册任何事件监听
  4. 请求中没有 ReadableStream 对象

预检请求:

在发送正式请求之前,会先发起一个 OPTIONS 预检请求到服务器,以获知服务器是否允许该实际请求,若不允许,则不再发送请求,其匹配规则如下:

  1. 请求方法为: PUTDELETECONNECTOPTIONSTRACEPATCH 之一
  2. 人为设置了 CORS安全部首字段集合 之外的字段
  3. 请求中的 XMLHttpRequestUpload 对象注册了任意事件监听器
  4. 请求中使用了 ReadableStream 对象

在跨域请求中,若服务端返回了正确的跨域响应部首: Access-Control-Allow-OriginAccess-Control-Allow-MethodAccess-Control-Allow-Headers , 则跨域请求能正常获取数据。

问题解决

根据以上了解的知识点,跟进遇到的问题,发现 axios 的请求部首 Content-Type 的值默认为 application/json;charset=utf-8 ,且 POST 请求数据为 json 格式,故进行 POST 请求会先发出预检请求,若服务端对预检请求的响应为不支持,则请求终止。

根据上面分析出的原因,以下列举两种解决方案:

完善服务端接口及跨域响应部首

使服务端接口支持 OPTIONS 方法,且对跨域预检请求的请求部首进行完整的响应匹配,表明服务器将接受后续的实际请求,则实际请求将被正常响应。

前端侧处理 axios 的 POST 请求数据

跨域时将请求转换为简单请求:

  1. 请求部首的 Content-Type 设为 application/x-www-form-urlencoded
  2. 处理 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 跨域请求详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms to Live By

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》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具