需求

  1. 封装常用请求
  2. 拦截器-请求锁
  3. 统一处理错误码

一、封装常用的请求

  解决痛点:不要每一个模块的api都还要写get,post,patch请求方法。直接将这些常用的方法封装好。

  解决方案:写一个类,封装好常用的请求

  部分源码如下

export default class PublicAPI {
constructor(url) {
this.url = url;
} get(params, filter) {
if (Array.isArray(params)) {
filter = typeof filter === 'object' ? JSON.stringify(filter) : filter;
let qs = filter ? '?filter=' + filter : '';
return axios.get(this.url + '/' + params.join('/') + qs);
}
params = params || {};
return axios.get(this.url, { params });
} delete(id) {
return axios.delete(`${this.url}/${id}`);
} post(params) {
return axios.post(this.url, params);
}
   //常用请求 都可以封装在这里
}

二、拦截器-请求锁

  解决痛点:限制同一时间发多个同一个请求

  解决方案:利用axios的拦截器 + axios.CancelToken,限制同一个请求多次发送

  源码如下

方案一:简单款

let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
let CancelToken = axios.CancelToken;
let removePending = (config) => {
for(let p in pending){
if(pending[p].u === config.url + '&' + config.method) { //当前请求在数组中存在时执行函数体
pending[p].f(); //执行取消操作
pending.splice(p, 1); //把这条记录从数组中移除
}
}
}

方案二:复杂款(这个是在掘金上看到的,原链接找不到了)

let pending = {};
/**
* cancelKey管理器
*
* @return {Object} 返回一个对象,对象暴露两个方法,一个可以获取本次请求的key,一个是设置本次请求的key
* @memberof HttpRequest
*/
let cancelKeyManager = () => {
const expose = {};
expose.setKey = function setKey(config) {
const { method, url, params, data } = config;
expose.key = `${method}|${url}`;
//expose.key = method === 'get' ? `${expose.key}&${JSON.stringify(params)}` : `${expose.key}&${JSON.stringify(data||{})}`;
};
expose.getKey = function getKey() {
return expose.key;
};
return expose;
}; /**
*处理请求拦截和请求取消
*
* @param {object} config axios配置对象
* @param {boolean} [isCancel=true] 标识是请求取消还是拦截请求
* @return {object} 返回axios配置对象
* @memberof HttpRequest
*/
let handleRequestCancel = (config, isCancel = false) => {
// 设置本次请求的key
const { setKey, getKey } = cancelKeyManager();
setKey(config);
const key = getKey();
const CancelToken = axios.CancelToken;
// 取消已经发出去的请求
if (isCancel) {
removeRequest(key, true);
// 设置本次请求的cancelToken
config.cancelToken = new CancelToken(c => {
pending[key] = c;
});
} else {
// 拦截本次请求
config.cancelToken = new CancelToken(c => {
// 将本次的cancel函数传进去
pending[key] = c;
removeRequest(key, true, c);
});
} return config;
}; /**
* 移除请求
*
* @param {string} key 标识请求的key
* @param {boolean} [isRequest=false] 标识当前函数在请求拦截器调用还是响应拦截器调用
* @param {function} c cancel函数
* @memberof HttpRequest
*/
let removeRequest = (key, isRequest = false, c) =>{
// 请求前先判断当前请求是否在pending中,如果存在有两种情况:
// 1. 上次请求还未响应,本次的请求被判为重复请求,则调用cancel方法拦截本次重复请求或者取消上一个请求
// 2. 上次请求已经响应,在response中被调用,清除key
console.log(key,pending);
if (pending[key]) {
if (isRequest) {
Message.error({
message: '请求过于频繁'
});
} else {
// 上一次请求在成功响应后调用cancel函数删除key
delete pending[key];
}
}
};

三、统一处理错误码

  解决痛点:每个请求都需要处理错误信息,特别是一些常用的错误(坚持能封装就封装的思想),当然具体业务处理逻辑这是各自处理啦!

  解决方案:用axios拦截器,将返回来的错误统一处理,最常用的就是401 token失效吧!一般是要前后端统一错误码的,固定的错误码做固定的事情!

  部分源码如下(感觉只适合部分)

axios.interceptors.response.use(
response => {
return new Promise((resolve, reject) => { //很重要 用promise 接收自定义错误码
let data = response.data;
if (data.code === 'ok') {
return resolve({
data: data.data || data || {},
response: response
});
} else {
switch (data.code) {
case '10500': //自定义code
reject({
response: {
code: '10500',
status: 500,
msg: data.msg
}
});
break;
default:
reject(response);
}
}
});
},error => {}
)

总结

  给出的源码比较分散,仅提供思路。

  在项目中这么一套全家桶用下来,十分巴适~~~

  有疑问可以给我留言,我会尽力解答哦

vue+axois 封装请求+拦截器(请求锁+统一错误)的更多相关文章

  1. axios源码解析 - 请求拦截器

    axios请求拦截器,也就是在请求发送之前执行自定义的函数. axios源码版本 - ^0.27.2 (源码是精简版) 平时在业务中会这样去写请求拦截器,代码如下: // 创建一个新的实例 var s ...

  2. Vue添加请求拦截器

    一.现象 统一处理错误及配置请求信息 二.解决 1.安装 axios  , 命令: npm install axios --save-dev 2.在根目录的config目录下新建文件 axios.js ...

  3. 细说vue axios登录请求拦截器

    当我们在做接口请求时,比如判断登录超时时候,通常是接口返回一个特定的错误码,那如果我们每个接口都去判断一个耗时耗力,这个时候我们可以用拦截器去进行统一的http请求拦截. 1.安装配置axios cn ...

  4. vue 路由拦截器和请求拦截器

    路由拦截器 已路由为导向 router.beforeEach((to,from,next)=>{ if(to.path=='/login' || localStorage.getItem('to ...

  5. Feign 请求拦截器和日志

    Feign 支持请求拦截器,在发送请求前,可以对发送的模板进行操作,例如设置请求头等属性,自定请求拦截器需要实现 feign.RequestInterceptor 接口,该接口的方法 apply 有参 ...

  6. 实现Feign请求拦截器,对请求header等参数进行转发

    参考:Feign传递请求头信息(Finchley版本) 问题:通过Feign远程调用服务,无法传递header参数. 解决方式:实现RequestInterceptor接口(对所有的Feign请求进行 ...

  7. http request 请求拦截器,有token值则配置上token值

    // http request 请求拦截器,有token值则配置上token值 axios.interceptors.request.use( config => { if (token) { ...

  8. axios封装的拦截器的应用

    axios拦截器   页面发送http请求,很多情况我们要对请求和其响应进行特定的处理:如果请求数非常多,单独对每一个请求进行处理会变得非常麻烦,程序的优雅性也会大打折扣.好在强大的axios为开发者 ...

  9. (vue.js)axios interceptors 拦截器中添加headers 属性

    (vue.js)axios interceptors 拦截器中添加headers 属性:http://www.codes51.com/itwd/4282111.html 问题: (vue.js)axi ...

随机推荐

  1. 直面秋招!非科班生背水一战,最终拿下阿里等大厂offer!

    前言 2020年已经接近到9月份了,很多粉丝朋友都对金九银十雀雀欲试了吧!也有很多朋友向我求教经验,因为我自己工作相对于稳定,在这里给大家分享一个粉丝朋友的经历,他作为一个曾经的菜鸡面试者,在不断的失 ...

  2. Sound Forge常规功能详解

    Sound Forge是一款有口皆碑的音频编辑软件,专为录音.母带处理和音频编辑开发.但是该如何使用Sound Forge呢,Sound Forge经常用到的功能有哪些呢?今天小编通过该文章给大家进行 ...

  3. 苹果电脑下载电影教程:如何用folx下载《小妇人》

    由西尔莎罗南.艾玛沃特森等知名影星重新演绎的<小妇人>又带动了新一轮的<小妇人>热潮.这部由露易莎创作的长篇小说,曾被多次拍摄,无论是小说本身,还是其影视资源,都能让观众回味无 ...

  4. u盘插电脑没反应的三大原因,以及解决方法

    相信大家在使用U盘的过程中免不了会遇到这样的情况:u盘虽然与电脑连接,但是插上后却没有反应.很多小伙伴都摸不着头脑不知道到底是哪里出了错.其实大家也不用过于心急,只要找到了原因便可很快得到解决. u盘 ...

  5. leetcode133. 克隆图

    给定无向连通图中一个节点的引用,返回该图的深拷贝(克隆).图中的每个节点都包含它的值 val(Int) 和其邻居的列表(list[Node]).示例: 输入:{"$id":&quo ...

  6. TCP接收窗口为什么变大了?

    今天用wireshark抓取TCP连接时的报文发现客户端的Win变大了,这里是使用了Window Scale来扩张TCP接收窗口,使得接收窗口可以大于65535字节. 首先1号包是TCP第一次握手连接 ...

  7. 好端端的数据结构,为什么叫它SB树呢?

    大家好,今天给大家介绍一个很厉害的数据结构,它的名字就很厉害,叫SB树,业内大佬往往叫做傻叉树.这个真不是我框你们,而是它的英文缩写就叫SBT. SBT其实是英文Size balanced tree的 ...

  8. 如何实现一个简易版的 Spring - 如何实现 Setter 注入

    前言 之前在 上篇 提到过会实现一个简易版的 IoC 和 AOP,今天它终于来了...相信对于使用 Java 开发语言的朋友们都使用过或者听说过 Spring 这个开发框架,绝大部分的企业级开发中都离 ...

  9. Linux下的MediaWiki的部署启动遇到的问题与解决方案

    1. MySQL安装不成功 解决方案:https://bbs.csdn.net/topics/394377536 2. no space left on device ubuntu 解决方案:http ...

  10. 获取Win和Linux系统启动时间,类似uptime功能,用于判断是否修改过系统时间

    目录 前言 测试代码 Win测试 Linux测试 总结 前言 有时候需要判断系统是否有修改过时间,最简单的方法就是获取当前时间A,然后sleep X秒,然后获取 时间B,如果 时间B - 时间A ≠ ...