项目中axios的封装


网络请求模块

功能:

  • 请求头中自动携带token
  • 未登录用户重定向到登录页
  • 请求重连
  • 支持取消请求("axios": ^0.22.0
// @/utils/request.js

import axois from 'axios';

const USER_NOT_LOGIN_CODE = '0000'; // 用户未登录
const USER_RESPONSE_CODE = '1000'; //  正常响应

// 创建axios实例
const service = axois.create({
    baseURL: `${process.env.VUE_APP_BASE_URL}/api`,
    timeout: 120000 // 请求超时时间
})

// request 拦截器设置
service.interceptors.request.use(
    config => {
        // 从localStorage中获取token
        const token = localStorage.getItem('token');
        if (token) {
            config.headers['token'] =  token // 请求头设置 token
        }
        return config
    },
    error => {
        Promise.reject(error)
    }
)

/**
 * 后端返回响应体结构
 * @param {string} code - 响应码
 * @param {boolean} success - 请求结果
 * @param {string} message - 提示信息
 * @param {object | array} result - 查询结果 
 */

// response 拦截器设置
service.interceptors.response.use(
    // HTTP状态码为 2xx 时进入到此回调
    response => {
        // 服务端返回的响应体
        const { success, result, code, message } = response.data

        // 根据响应码进行响应的逻辑操作
        // 未登录
        if (code === USER_NOT_LOGIN_CODE) {
            // 转到登录页
            window.location.href = 'xxxx/login';
        } else if (code !== USER_RESPONSE_CODE) { // 
            return Promise.reject(new Error(message || 'Error'))
        } else {
            return response.data
        }
    },
    // HTTP状态码非 2xx 时进入到此回调
    error => {
        let config = error.config;
        if (!config) return Promise.reject(error);

        // 请求重连功能
        const { retryCount = 0, retryDelay = 300, retryTimes = 2 } = config;
        // 记录已经重试的次数
        config.retryCount = retryCount;

        // 判断是否超过了重试次数
        if (retryCount >= retryTimes) {
            return Promise.reject(error);
        }
        // 增加重试次数
        config.retryCount++;
        // 延时处理后重新发起请求
        setTimeout(() => {
            service(config);
        }, retryDelay);
    }
)

export default service

业务请求模块

// @/apis/user.js
import request from '@/utils/request';

const urls = {
    logout: '/user/logout', // 登出
    userList: '/user/list', // 用户列表
    upload: '/file/upload', // 上传文件
    download: '/file/download' // 下载文件 
}

// 登出
export function logout(params={}) {
    return request({
        method: 'get',
        url: urls.logout,
        params
    })
}

// 获取用户列表
export function getUserList(data, signal) {
    return request({
        method: 'post',
        url: urls.userList,
        data,
        signal
    })
}

// 上传文件
export function uploadFile(data) {
    return request({
        url: urls.upload,
        method: 'post',
        headers: {
            'Content-Type': 'multipart/form-data'
        },
        data
    })
},

// 下载文件
export function downloadFile(params) {
    return request({
        url: urls.download,
        method: 'get',
        responseType: 'blob', // 下载的文件为二进制blob对象,根据后端来决定
        params
    })
}

组件

<template>
    <div>用户模块</div>
</template>

<script>
import { logout, getUserList, uploadFile, downloadFile } from '@/apis/user'
export default {
    name: 'UserList',
    data() {
        return {
            pageInfo: {
                pageNo: 1,
                pageSize: 10
            }
        }
    },
    methods: {
        // 获取用户列表
        async getUserList() {
            const controller = new AbortController();

            // 3秒后自动取消请求
            setTimeout(() => {
                controller.abort();
            }, 3000);
            try {
                const response = await getUserList(this.pageInfo, controller.signal);
                console.log(response);
            } catch (error) {
                console.error(error);
            }
        },

        // 登出
        async logout() {
            try {
                const response = await logout();
                console.log(response);
            } catch (error) {
                console.error(error);
            }
        },

        // 上传
        async upload(file) {
            // 需要使用 FormData的格式上传文件
            const formData = new FormData()
            formData.append('file', file.file)

            try {
                const response = await uploadFile(formData)
            } catch (error) {
                console.error(error);
            }   
        },

        // 下载
        async download() {
            try {
                let res = await downLoadFile({ id: 1 });
                let URL = window.URL || window.webkitURL;
                const blobUrl = URL.createObjectURL(res);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = blobUrl;
                a.setAttribute('download', decodeURI(`文件${new Date().getTime()}.xlsx`));
                if (a.download == 'undefined') {
                    a.setAttribute('target', '_blank')
                }
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
                window.URL.revokeObjectURL(blobUrl);
            } catch(error) {
                console.log(error)
            }
        }
    }
}
</script>

文章作者: Snail-Lu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Snail-Lu !
  目录