vue3 封装 axios [ 请求拦截、响应拦截 ]

vue3 axios 的封装与 vue2 整体相同,细节需注意。整体思路可分为四步:

1、创建 axios 实例;

2、请求拦截器,携带 token 校验参数;

3、响应拦截器,剥离无效数据、处理 token 失效;

4、封装 axios 函数;

5、调用封装函数;

一、创建 axios 实例

const service = axios.create({
  baseURL: '', // 所有的请求地址前缀部分
  timeout: 60000, // 请求超时时间毫秒
  withCredentials: true, // 异步请求携带cookie
  headers: {
    // 设置后端需要的传参类型
    'Content-Type': 'application/json',
    'token': 'your token',
    'X-Requested-With': 'XMLHttpRequest',
  },
});

二、添加请求拦截器

service.interceptors.request.use(
  // eslint-disable-next-line func-names
  function (config) {
    // 在发送请求之前做些什么
    const token = getToken();
    if (token) {
      if (!config.headers) {
        config.headers = {};
      }
      config.headers.Authorization = `XXXX ${token}`;
    }
    // 若请求方式为post,则将data参数转为JSON字符串
    if (config.method === 'POST') {
      config.data = JSON.stringify(config.data);
    }
    return config;
  },
  // eslint-disable-next-line func-names
  function (error) {
    // 对请求错误做些什么
    // eslint-disable-next-line no-console
    console.log(error);
    return Promise.reject(error);
  }
);

三、添加响应拦截器

service.interceptors.response.use(
  // eslint-disable-next-line func-names
  function (response) {
    return response.data;
  },
  // eslint-disable-next-line func-names
  function (error) {
    const code = error.response.status;
    const dataAxios = error.response.data;
    switch (code) {
      case 400:
        {
          let msg = '';
          Object.keys(dataAxios).forEach((k) => {
            msg += `${k} - ${dataAxios[k].toString()}`;
          });
          Notification.error({
            title: '数据提交异常!',
            duration: 5000,
            content: msg,
          });
        }
        break;
      case 401:
        Notification.error({
          title: '服务器消息',
          duration: 5000,
          content: 'Token 已过期,请重新登录!',
        });
        setToken('');
        break;
      case 403:
        Notification.error({
          title: '服务器消息',
          duration: 5000,
          content: 'Token 已过期,请重新登录!',
        });
        setToken('');
        break;
      case 404:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '请求地址出错!',
        });
        break;
      case 408:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '请求超时!',
        });
        break;
      case 500:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '服务器内部错误!',
        });
        break;
      case 501:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '服务未实现!',
        });
        break;
      case 502:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '网关错误!',
        });
        break;
      case 503:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '服务不可用!',
        });
        break;
      case 504:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '网关超时!',
        });
        break;
      case 505:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: 'HTTP版本不受支持!',
        });
        break;
      default:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '请求失败!',
        });
    }
    return Promise.reject(error);
  }
);

四、封装调用函数

/src/http/index.ts [ 完整代码 ]

import axios from 'axios';
import { getToken, setToken } from '@/utils/auth';
import { Notification } from '@arco-design/web-vue';

// 创建一个 axios 实例
const service = axios.create({
  baseURL: '', // 所有的请求地址前缀部分
  timeout: 60000, // 请求超时时间毫秒
  withCredentials: true, // 异步请求携带cookie
  headers: {
    // 设置后端需要的传参类型
    'Content-Type': 'application/json',
    'token': 'your token',
    'X-Requested-With': 'XMLHttpRequest',
  },
});

// 添加请求拦截器
service.interceptors.request.use(
  // eslint-disable-next-line func-names
  function (config) {
    // 在发送请求之前做些什么
    const token = getToken();
    if (token) {
      if (!config.headers) {
        config.headers = {};
      }
      config.headers.Authorization = `EIMS ${token}`;
    }
    // 若请求方式为post,则将data参数转为JSON字符串
    if (config.method === 'POST') {
      config.data = JSON.stringify(config.data);
    }
    return config;
  },
  // eslint-disable-next-line func-names
  function (error) {
    // 对请求错误做些什么
    // eslint-disable-next-line no-console
    console.log(error);
    return Promise.reject(error);
  }
);

// 添加响应拦截器
service.interceptors.response.use(
  // eslint-disable-next-line func-names
  function (response) {
    return response.data;
  },
  // eslint-disable-next-line func-names
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    const code = error.response.status;
    const dataAxios = error.response.data;
    switch (code) {
      case 400:
        {
          let msg = '';
          Object.keys(dataAxios).forEach((k) => {
            msg += `${k} - ${dataAxios[k].toString()}`;
          });
          Notification.error({
            title: '数据提交异常!',
            duration: 5000,
            content: msg,
          });
        }
        break;
      case 401:
        Notification.error({
          title: '服务器消息',
          duration: 5000,
          content: 'Token 已过期,请重新登录!',
        });
        setToken('');
        break;
      case 403:
        Notification.error({
          title: '服务器消息',
          duration: 5000,
          content: 'Token 已过期,请重新登录!',
        });
        setToken('');
        break;
      case 404:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '请求地址出错!',
        });
        break;
      case 408:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '请求超时!',
        });
        break;
      case 500:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '服务器内部错误!',
        });
        break;
      case 501:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '服务未实现!',
        });
        break;
      case 502:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '网关错误!',
        });
        break;
      case 503:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '服务不可用!',
        });
        break;
      case 504:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '网关超时!',
        });
        break;
      case 505:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: 'HTTP版本不受支持!',
        });
        break;
      default:
        Notification.error({
          title: '服务器提示',
          duration: 5000,
          content: '请求失败!',
        });
    }
    return Promise.reject(error);
  }
);

export default service;

五、调用封装包

import axios from '@/http/index';

export function getData(pager: any, val: any) {
  return axios({
    url: `/api/data/?p=${pager.pageNum}&page_size=${pager.pageSize}&search=${val}`,
    method: 'get',
  });
}

export function Ambient(data: any, option: any, id: any) {
  const method = option === 'add' ? 'post' : 'patch';
  const url = option === 'add' ? '' : `${id}/`;
  return axios({
    url: `/api/data/${url}`,
    method,
    data,
  });
}

export function delAmbient(id: any) {
  return axios({
    url: `/api/data/${id}/`,
    method: 'delete',
  });
}

参考:https://zhuanlan.zhihu.com/p/439486263
展开阅读全文
存在即是合理,一切皆有可能。
上一篇

RSA 非对称加密 - 秘钥对生成,加密/解密,签名/验签

你也可能喜欢

  • 暂无相关文章!

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片
serven 管理员
存在即是合理,一切皆有可能。
返回顶部

微信扫一扫

微信扫一扫