axios请求二次封装之避免重复发送请求

作者:阿选不出来 时间:2024-04-09 10:45:32 

前言

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

axios 是目前最优秀的 HTTP 请求库之一, 我们封装 axios 请求也是为了让代码看的更加清晰, 后期好维护.

目的

  • 实现请求拦截

  • 实现响应拦截

  • 常见错误处理

  • 不能请求头设置

  • api 集中式管理

(取消重复请求,重复发送请求, 请求缓存等情况均还未实现)

文件结构

axios请求二次封装之避免重复发送请求

实现

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

标签:axios,二次封装,重复发送
0
投稿

猜你喜欢

  • Python字典fromkeys()方法使用代码实例

    2021-07-09 09:54:38
  • 在django admin详情表单显示中添加自定义控件的实现

    2023-09-24 18:56:00
  •  Go 语言实现 HTTP 文件上传和下载

    2023-06-23 01:42:24
  • 通过cmd进入python的步骤

    2022-05-27 05:23:31
  • Python range、enumerate和zip函数用法详解

    2021-06-29 22:24:06
  • 浅谈pandas筛选出表中满足另一个表所有条件的数据方法

    2022-08-12 14:29:13
  • 关于MySql链接url参数的设置

    2024-01-19 17:45:14
  • Golang中异常处理机制详解

    2024-02-17 17:05:50
  • python中把元组转换为namedtuple方法

    2021-12-04 22:13:04
  • Python 爬虫学习笔记之多线程爬虫

    2022-10-03 15:10:37
  • windows 7安装ORACLE 10g客户端的方法分享

    2012-07-11 15:36:18
  • Python 矩阵转置的几种方法小结

    2023-01-20 15:51:56
  • 深入解析JavaScript框架Backbone.js中的事件机制

    2024-05-03 15:58:59
  • 浅析Oracle中sys、system和Scott用户下的数据库连接问题

    2023-07-02 15:14:06
  • python Django模板的使用方法

    2021-06-09 15:29:14
  • Python实现带图形界面的炸金花游戏

    2021-06-21 15:41:56
  • Go语言中DateTime的用法介绍

    2024-04-27 15:31:55
  • django DRF图片路径问题的解决方法

    2023-02-05 15:25:46
  • Jquery中Ajax 缓存带来的影响的解决方法

    2011-05-21 16:14:00
  • python 视频下载神器(you-get)的具体使用

    2023-03-18 19:30:58
  • asp之家 网络编程 m.aspxhome.com