vue+axois 封装请求+拦截器(请求锁+统一处理错误码)

摘要:
需求封装通用请求拦截器-请求锁统一处理错误代码1.封装通用请求以解决难点:不要在每个模块的api中编写get、post和patch请求方法。解决方案:使用axios拦截器统一处理返回的错误。最常见的是401token失败!通常,有必要统一前后错误代码。修复错误代码可以修复问题!在项目中使用这样一套家庭桶是非常舒适的~~~如果你有任何问题,请给我留言,我会尽力回答

 需求

  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 封装请求+拦截器(请求锁+统一处理错误码)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇eclipse中新建C++工程V-REP下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Yii2基本概念之——配置(Configurations)

在Yii中创建新对象或者初始化已经存在的对象广泛的使用配置,配置通常包含被创建对象的类名和一组将要赋值给对象的属性的初始值,这里的属性是Yii2的属性。还可以在对象的事件上绑定事件处理器,或者将行为附加到对象上。从而在定义了对象的初始值的同时,充分规定对象的运行时的动态特性。 以下代码中的配置被用来创建并初始化一个数据库连接: $config = [...

使用springcloud gateway搭建网关(分流,限流,熔断)

Spring Cloud Gateway Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。 Spring Cloud Gatewa...

android http 和https请求

1 private static final int CONNECTION_TIMEOUT = 10000; 2 3 public static String doHttpGet(String serverURL) throws Exception { 4 HttpParams httpParameters...

Qt工程文件Pro介绍(转)

转载请注明:http://blog.163.com/hu_cuit/blog/static/122849143201127104232142/ 我也才开始学习QT的菜鸟。但是前几天有同学叫我给他讲一下QT的基本的编程。在过程中我发现了自己的不足,这个要改进。因为我相信我会变成老鸟的。当然我发现同学对QT的工程文件不是很了解,又恰好我以前研究过,看过一些资料...

vue 项目中使用 wangEditor

1,vue中安装wangEditor  使用的npm安装 npm install wangeditor --save 2,创建公用组件  在components中创建wangEditor文件夹 组件内容为 <template lang="html"> <div class="editor"> <div ref="t...

Ext.js弹窗上传文件

1.构建上传组件 var fileUpload = new Ext.FormPanel({ id:'fileUpload', frame:true, fileUpload:true, items:[{ xtype: 'filefield',...