axios 跨域请求详解

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

内容简介:写这篇文章的背景是因为之前遇到的,在跨域的情况下通过 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 跨域请求详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

数据挖掘十大算法

数据挖掘十大算法

(美)吴信东(Xindong Wu)、(美),库玛尔 ,(Vipin Kumar) / 李文波、吴素研 / 清华大学出版社 / 2013-5 / 39.00元

《世界著名计算机教材精选:数据挖掘十大算法》详细介绍了在实际中用途最广、影响最大的十种数据挖掘算法,这十种算法是数据挖掘领域的顶级专家进行投票筛选的,覆盖了分类、聚类、统计学习、关联分析和链接分析等重要的数据挖掘研究和发展主题。《世界著名计算机教材精选:数据挖掘十大算法》对每一种算法都进行了多个角度的深入剖析,包括算法历史、算法过程、算法特性、软件实现、前沿发展等,此外,在每章最后还给出了丰富的习......一起来看看 《数据挖掘十大算法》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具