axios请求二次封装之避免重复发送请求
作者:阿选不出来 发布时间:2024-04-09 10:45:32
标签:axios,二次封装,重复发送
前言
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
axios 是目前最优秀的 HTTP 请求库之一, 我们封装 axios 请求也是为了让代码看的更加清晰, 后期好维护.
目的
实现请求拦截
实现响应拦截
常见错误处理
不能请求头设置
api 集中式管理
(取消重复请求,重复发送请求, 请求缓存等情况均还未实现)
文件结构
实现
index.js内代码如下:
引入
// 引入 axios
import axios from 'axios';
// 请求配置单独写一个文件 baseurl.js
import serverConfig from './baseurl.js'
创建一个实例
const serviceAxios = axios.creat({
baseURL: serverConfig.baseURL, //基础请求地址
timeout: 1000 , //请求超时设置
withCredentials: false, // 跨域请求是否需要携带 cookie
})
请求拦截
serviceAxios.interceptors.request.use(
(config) => {
console.log("请求配置", config);
// 是否使用 Token,
if(serverConfig.useTokenAuthorization) {
config.headers["Authorization"] = localStorage.getItem("token");
}
// 设置请求头
if(config.method === "post") {
config.headers["content-type"] = "application/x-ww-form-urlencoded";
// config.data = qs.stringify(config.data); //序列化 效果等同于下行代码
config.requestType = "form"
} else {
config.headers["content-type"] = "application/json"
}
// 返回
return config
},
(error) => {
Promise.reject(error)
}
)
响应拦截
serviceAxios.interceptors.response.use(
(res) => {
console.log("响应拦截", res);
let data = res.data;
// 处理自己的业务逻辑,如 token 是否过期...
return data;
},
(error) => {
let message = ""
if(error && error.response) {
switch (error.response.status) {
case 302:
message = "接口重定向了! ";
break;
case 400:
message = "参数不正确! ";
break;
case 401:
message = "您未登录, 或者登录已经超时, 请先登录! "
break;
case 403:
message = "您还没有权限操作! ";
break;
case 404:
message = `请求地址出错: ${error.response.config.url}`;
break;
case 408:
message = "请求超时! ";
break;
case 409:
message = "系统已存在相同数据! "
break;
case 500:
message = "服务器内部错误! "
break;
case 501:
message = "服务未实现! "
break;
case 502:
message = "回答错误! "
break;
case 503:
message = "服务不可用"
break;
case 504:
message = "服务暂时无法访问, 请稍后再试"
break;
case 505:
message = "HTTP 版本不受支持! "
break;
default:
message = "异常问题, 请联系管理员! "
break;
}
}
return Promise.reject(message);
}
);
取消重复发送请求
实现思想
唯一标识值 : 每次发起请求的时候根据请求的方式,请求URL,请求携带参数设置一个唯一标识值.
请求队列: 创建一个map对象储存请求的唯一标识值.
每次发送请求的时候, 在请求拦截中判断请求队列中是否存在这个请求, 存在就说明这个请求正在进行中,那么就取消正在发送的请求,重新发送请求; 不存在就将本次请求加入请求队列中.
在响应拦截中将本次请求从请求队列中移除.
📘生成唯一标识值函数
import qs from 'qs'
function regsoleKey(config){
const {method, url, params, data } = config;
return [method, url, qs.stringify(params), qs.stringify(data)].join('&')
}
📘将请求加入请求队列函数
const reqQueue = new Map();
function addreqQueue(config){
//调用生成唯一标识值函数, 生成 requestKey
const requestKey = regsoleKey(config);
//为每个请求创建一个专属的 CancelToken(用于取消请求)
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel)=>{
// 判断 reqQueue 中是否含有 requestKey,
// 将 requestKey 与 CancelToken 以键值对的形式保存到map对象中
if(!reqQueue.has(requestKey)){
reqQueue.set(requestKey,cancel)
}
});
}
📘将请求从请求队列移除
function removereqQueue(config){
// 标识值
const requestKey = generateReqKey(config);
if(reqQueue.has(requestKey)){
// 取消之前发出请求
const cancelToken = reqQueue.get(requestKey);
cancelToken(requestKey);
// 从队列移除
reqQueue.delete(requestKey);
}
}
💧请求 *
serviceAxios.interceptors.request.use(
function(config) {
removereqQueue(config); // 检查是否重复发送请求
addreqQueue(config); //将本次请求加入请求队列
return config
},
(error) => {
return Promise.reject(error)
}
)
💧响应 *
serviceAxios.interceptors.response.use(
(res) => {
removereqQueue(res.config); //请求从请求队列移除
return res
},
(error) => {
removereqQueue(error.config || {}); //请求从请求队列移除
//....
}
)
// 最后
export default serviceAxios
baseurl.js代码如下
const serverConfig = {
baseURL: 'https://fm-emo-music-api.vercel.app',
useTokenAuthorization: true, //是否开启 token 验证
}
export default serverConfig
api.js代码如下
// 引入index.js
import serviceAxios from './index.js'
// get实例
export const VideoRecommendLike = (params) => {
return serviceAxios({
method: "get",
url: "/dj/personalize/recommend",
params,
})
}
// post实例
export const ConfirmPhone = (data) =>{
return serviceAxios({
method: "post",
url: "/captcha/sent",
data,
})
}
调用
如何在原生js文件内调用?
首先引入axios文件
<!-- axios请求文件 -->
<script src="/src/utils/axios.js"></script>
再引入带有axios请求的js文件, 请求文件内使用es6新语法按需引入api.js文件
例:
import {useRouter} from '../../router/app.js'
如何在Vue文件内使用?
示例:
// 按需引入请求接口
import {emailCounts} from "@/api/api.js"
export default {
...
// 异步进行axios请求
methods: {
async comein(){
let res = await emailCount(params)
console.log(res)
}
}
}
来源:https://blog.csdn.net/m0_63300737/article/details/127194323


猜你喜欢
- swagger介绍Swagger本质上是一种用于描述使用JSON表示的RESTful API的接口描述语言。Swagger与一组开源软件工具
- 判断类型在Python中我们可以使用type进行类型的判断#我们想看一个对象的的类型可以这样class A: passa = A
- Python 的代码风格由 PEP 8 描述。这个文档描述了 Python 编程风格的方方面面。在遵守这个文档的条件下,不同程序员编写的 P
- 前端JS中使用XMLHttpRequest 2上传图片到服务器,PC端和大部分手机上都正常,但在少部分安卓手机上上传失败,服务器上查看图片,
- 在 HTML 中,有两种方式来表现文本框:一种是使用<input>元素的单行文本框,另一种是使用 <textarea>
- 在日常生活中,随机数对于我们而言并不陌生,例如手机短信验证码就是一个随机的数字字符串;对于统计分析、机器学习等领域而言,通常也需要生成大量的
- flags参数re.I IGNORECASE 忽略字母大小写re.L &nb
- 本文实例为大家分享了python实现飞行棋的具体代码,供大家参考,具体内容如下import random# 地图初始坐标Maps = [0]
- Python中使用ElementTree可以很方便的处理XML,但是产生的XML文件内容会合并在一行,难以看清楚。如下格式:<root
- python的pdb调试命令的命令整理及实例一、命令整理pdb调试命令完整命令简写命令描述argsa打印当前函数的参数breakb设置断点c
- 用analyze进行处理,定期进行处理ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb1_name
- 数据库备份的分类物理备份:数据库操作系统的物理文件(如数据文件,日志文件等)的备份物理备份的方法:冷备份(脱机备份):是在关闭数据库时候进行
- 前言selenium处理文件上传大致会有两种情况,一种是文件上传使用的是input标签元素,即<input type="fi
- 在程序的开发过程中,处理分页是大家接触比较频繁的事件,因为现在软件基本上都是与数据库进行挂钩的。但效率又是我们所追求的,如果是像原来那样把所
- 如何用ASP发送带附件的邮件?请问如何用CDONTS组件发送带附件的邮件? 见下列代码:<%&nb
- 最近想做实时目标检测,需要用到python开启摄像头,我手上只有两个uvc免驱的摄像头,性能一般。利用python开启摄像头费了一番功夫,主
- %matplotlib inline是一个魔法函数(Magic Functions)。官方给出的定义是:IPython有一组预先定义好的所谓
- 本文实例讲述了python迭代器的简单用法,分享给大家供大家参考。具体分析如下:生成器表达式是用来生成函数调用时序列参数的一种迭代器写法生成
- 有时候很多朋友访问自己的asp或php等程序页面时出现一些错误,就是页面无法显示也没有详细的错误信息,就算iis中开启了显示详细的错误也不能
- 一、进程介绍进程:正在执行的程序,由程序、数据和进程控制块组成,是正在执行的程序,程序的一次执行过程,是资源调度的基本单位。程序:没有执行的