美文网首页vue 插件案例
Axios最完整封装适用于Vue、React

Axios最完整封装适用于Vue、React

作者: 葛明路 | 来源:发表于2020-09-25 16:08 被阅读0次
    import axios from 'axios';
    import Toast from "zarm/lib/toast"
    import "zarm/lib/toast/style/css"
    
    let appId = "sdjhb-jdhoo-f265-djbhfj-iui"   //应用识别码,会在每一个url地址上拼接这个属性
    
    let stayTime = 3000 //设置zarmUI库Toast(轻提示)组件的停留时间
    
    /**
     * 设置超时时间和跨域是否允许携带凭证
     */
    axios.defaults.timeout = 10000; //10秒
    axios.defaults.withCredentials = true;
    
    /**
     * 设置post请求头
     * application/json;charset=UTF-8   JSON格式
     * application/x-www-form-urlencoded;charset=UTF-8  Form表单格式
     */
    axios.defaults.headers['Content-Type'] = 'application/json;charset=UTF-8';
    
    var CancelToken = axios.CancelToken;
    let sources = []  // 定义数组用于存储每个ajax请求的取消函数及对应标识
    
    /**
     * 请求防抖当一个url地址被请求多次就会取消前一次请求
     */
    let removeSource = (config) => {
        for (let source in sources) {
            // 当多次请求相同时,取消之前的请求
            if (sources[source].umet === config.url + '&' + config.method) {
                sources[source].cancel("取消请求")
                sources.splice(source, 1)
            }
        }
    }
    
    /**
     * 请求拦截器
     */
    axios.interceptors.request.use(config => {
        removeSource(config)
        config.cancelToken = new CancelToken((c) => {
            // 将取消函数存起来
            sources.push({ umet: config.url + '&' + config.method, cancel: c })
        })
        return config;
    }, error => {
        return Promise.reject(error)
    }
    )
    
    // 响应拦截器
    axios.interceptors.response.use(config => {
        if (config.data.statusCode >= 3000) {
            Toast.show({ content: config.data.msg, stayTime })
        }
        removeSource(config.config)
    
        return config.data;
    }, error => {
        if (!error.response) return
        switch (error.response.status) {
            // 401: 未登录
            // 未登录则跳转登录页面,并携带当前页面的路径
            // 在登录成功后返回当前页面,这一步需要在登录页操作。                
            case 401:
                if (window.location.hostname === "localhost") {
                    axios.post("/api/v1/login?client_name=form", {
                        "userName": "lixiaoyao4_vendor",
                        "password": 123456
                    })
                } else {
                    window.location = error.response.headers.locationurl;
                }
                break;
    
            // 403 token过期
            // 登录过期对用户进行提示
            // 清除本地token和清空vuex中token对象
            // 跳转登录页面                
            case 403:
                Toast.show({ content: "登录过期,请重新登录", stayTime })
                // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 
                if (window.location.hostname === "localhost") {
                    axios.post("/api/v1/login?client_name=form", {
                        "userName": "lixiaoyao4_vendor",
                        "password": 123456
                    })
                } else {
                    window.location = error.response.headers.locationurl;
                }
                break;
    
            // 404请求不存在
            case 404:
                Toast.show({ content: "访问资源不存在", stayTime })
                break;
            // 其他错误,直接抛出错误提示
            default:
                Toast.show({ content: error.response.data.message, stayTime })
        }
        return Promise.reject(error.response)
    }
    )
    
    /**
     * get方法,对应get请求
     * @param {String} url [请求的url地址]
     * @param {Object} params [请求时携带的参数]
     */
    function get(url, params) {
        return new Promise((resolve, reject) => {
            axios.get(url, {
                params: {
                    ...params,
                    appId
                },
            }).then(res => {
                resolve(res);
            }).catch(err => {
                reject(err.data)
            })
        });
    }
    
    /**
     * post方法,对应post请求
     * @param {String} url [请求的url地址]
     * @param {Object} params [请求时携带的参数]
     */
    function post(url, params) {
        if (url.indexOf("?") === -1) {
            url += `?appId=${appId}`
        } else {
            url += `&appId=${appId}`
        }
        return new Promise((resolve, reject) => {
            axios.post(`${url}`, params)
                .then(res => {
                    resolve(res);
                })
                .catch(err => {
                    reject(err)
                })
        });
    }
    
    // 对外暴露
    export { post, get }
    

    相关文章

      网友评论

        本文标题:Axios最完整封装适用于Vue、React

        本文链接:https://www.haomeiwen.com/subject/trpfuktx.html