Vue axios库避免重复发送请求的示例介绍

   2023-03-08 学习力0
核心提示:目录目的文件结构实现请求拦截响应拦截取消重复发送请求调用目的实现请求拦截实现响应拦截常见错误处理不能请求头设置api 集中式管理(取消重复请求,重复发送请求, 请求缓存等情况均还未实现)文件结构实现index.js内代码如下:引入// 引入 axiosimport axios fr

目的

  • 实现请求拦截
  • 实现响应拦截
  • 常见错误处理
  • 不能请求头设置
  • api 集中式管理

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

文件结构

Vue 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 {<!--{cke_protected}{C}%3C!%2D%2D%20%2D%2D%3E-->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
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • vue3+TS 自定义指令:长按触发绑定的函数
    vue3+TS 自定义指令:长按触发绑定的函数而然间看到一个在vue2中写的长按触发事件的自定义指定,想着能不能把他copy到我的vue3项目中呢。编写自定义指令时遇到的几个难点1.自定义指令的类型在ts中写任何东西都要考虑到类型的问题,自定义指令的类型问题依然存
    03-08
  • Vue生命周期 vue生命周期几个阶段
    Vue生命周期 vue生命周期几个阶段
    官网解释一、Vue的生命周期Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom - 渲染、更新 - 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期。Vue2生命周期:1.beforeCreate(创建前)数据观测和初始化事件还未开始,此时 dat
    03-08
  • vue 中安装并使用echart
    vue 中安装并使用echart
    本文为博主原创,转载请注明出处:1.安装echart 依赖:  安装命令: npm install echarts --save  在vscode 的终端窗口进行执行,如图所示:   执行完之后,查看 项目中的echart 版本依赖是否添加成功:  package-lock.json 中有具体的echart 依赖
    03-08
  • day04-Vue01
    day04-Vue01
    Vue011.Vue是什么?Vue(读音/vju:/,类似于view)是一个前端框架,依据构建用户界面Vue的核心库只关注视图层,不仅易于上手,还便于与第三方库或者项目整合支持和其他类库结合使用开发复杂的单页应用非常方便Vue是Vue.js的简称官网:Vue.js - 渐进式 JavaScr
    03-08
  • Vue + Element 自定义上传封面组件
    Vue + Element 自定义上传封面组件
    前一段时间做项目,频繁使用到上传图片组件,而且只上传一个封面,于是想着自定义一个图片封面上传组件。先来看一下效果:                      第一张图片是上传之前,第二张图片是上传成功后,第3张图片是鼠标放上去之后的效果! 首先整理需
    03-08
  • 基于ZR.VUE 前端的改造,页面刷新报错
     问题描述:前后端分离开发,分开部署. 页面刷新 直接报404 错误的解决办法提示:  先在 .env.development 中 配置 VUE_APP_BASE_API , 将 '/' 替换为 后端地址 'http://localhost:8888/'如果是对应的发布的正式环境,也要修改  .env.production 的VUE_APP_
    03-08
  • Vue3 企业级优雅实战 - 组件库框架 - 9 实现组
    上文搭建了组件库 cli 的基础架子,实现了创建组件时的用户交互,但遗留了 cli/src/command/create-component.ts 中的 createNewComponent 函数,该函数要实现的功能就是上文开篇提到的 —— 创建一个组件的完整步骤。本文咱们就依次实现那些步骤。(友情提示
    03-08
  • vue-3 this概念
    一、this概念官方是这样说的:在 setup()内部,this 不会是该活跃实例的引用因为 setup() 是在解析其它组件选项之前被调用的,所以 setup() 内部的 this 的行为与其它选项中的 this 完全不同这在和其它选项式 API 一起使用 setup() 时可能会导致混淆啥意思呢
    03-08
  • vue3和百度地图关键字检索 定位 点击定位
    vue3和百度地图关键字检索 定位 点击定位
    效果图在index.html中引入百度地图开放平台  去申请你的ak 非常的简单可以自己百度 一下!-- 这个用官网给的有好多警告 更具百度的把 https://api.map.baidu.com/getscript?v=2.0ak=xxxxxxxxxxxxxxxxxxxxx 换为这个就没有那么多 报错了 --scripttype="text/j
    03-08
  • Vue集成lodop插件实现打印功能 vue打印console
    Vue集成lodop插件实现打印功能 vue打印console
    目录VUE简单使用lodop1.创建LodopFuncs.js文件2.在打印功能vue页面引入LodopFuncs3.执行打印方法4.打印接口函数官网样例说明5.完整页面示例VUE 集成LODOP插件打印Lodop、C-Lodop使用说明及样例http://www.lodop.net/LodopDemo.htmlVUE简单使用lodop1.创建Lodo
    03-08
点击排行