axios拦截器,如何批量处理请求响应

axios拦截器

  • axios特性
  • axios拦截器
  • 具体实现
  • 进一步分离封装

axios特性

  • 从浏览器创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF

axios拦截器

在请求或响应被 then 或 catch 处理前拦截它们。

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });

具体实现

新建request.js,写入以下内容:

import axios from 'axios';
import qs from 'qs';
//操作正常code,支持String、Array、int多种类型
const successCode = [200, 1];
//登录失效code
const invalidCode = -1;
//无权限code
const noPermissionCode = 401;
// 请求超时时间(毫秒)
const timeout = 2000;
// 基础url地址
const baseURL = '/api'
/**
 *
 * @description 处理code异常
 * @param {*} code
 * @param {*} msg
 */
const handleCode = (code, msg) => {
  switch (code) {
    // 掉线
    case invalidCode:
      alert('您已掉线,或者访问权限出错,请重新登录!');
      break;
    // 无权限
    case noPermissionCode:
      router.push({ path: '/401' }).catch(() => { });
      break;
    // 其他情况
    default:
      alert(msg || `后端接口${code}异常`);
      break;
  }
};


// 创建axios实例
const instance = axios.create({
  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL,
  // 指定请求超时的毫秒数
  timeout,
  // 自定义请求头
  headers: {
    'Content-Type': 'application/json;charset=UTF-8',
  }
});


// 请求前拦截
instance.interceptors.request.use(
  (config) => {
    // 如果请求头声明需要formData数据,则使用qs进行处理
    if (
      config.data &&
      config.headers['Content-Type'] === 'application/x-www-form-urlencoded;charset=UTF-8'
    )
      config.data = qs.stringify(config.data);
    // 也可以在这里对接口传递公共参数
    return config;
  },
  (error) => {
    // 抛出错误
    return Promise.reject(error);
  }
);
// 响应拦截
instance.interceptors.response.use(
  (response) => {
    const res = response.data;
    const { data } = response;
    const { code, msg } = data;

    // 操作成功
    // 此处根据请求返回修改,成功code
    if (successCode.indexOf(code) !== -1) {
      return res;
    } else {
      // 请求失败
      // 校验失败code,处理场景
      handleCode(code, msg);
      return Promise.reject();
    }
  },
  (error) => {
    const { response, message } = error;
    // 如果返回有data,校验失败code
    if (error.response && error.response.data) {
      const { status, data } = response;
      handleCode(status, data.msg || message);
      return Promise.reject(error);
    } else {
      // 提示其他异常
      let { message } = error;
      if (message === 'Network Error') {
        message = '后端接口连接异常';
      }
      if (message.includes('timeout')) {
        message = '后端接口请求超时';
      }
      if (message.includes('Request failed with status code')) {
        const code = message.substr(message.length - 3);
        message = '后端接口' + code + '异常';
      }
      ElMessage.error(message || `后端接口未知异常`);
      return Promise.reject(error);
    }
  }
);

export default instance;

在需要使用的页面进行调用

import request from '@/utils/request.js';
request({
  url: '/login', // /api/login
  method: 'post',
  data: {
    account: 'admin',
    password: '123456'
  },
}).then(res => {
  // 处理逻辑
  console.log(res);
});

进一步分离封装

上一步咱们将axios拦截器进行了封装,一般项目工程化会将所有的接口封装到一个js中

下面是封装了几个跟用户信息相关的接口:

import request from '@/utils/request.js';
export const login = async (data) => {
  return request({
    url: '/login',
    method: 'post',
    data,
  });
};

export const getUserInfo = (accessToken) => {
  return request({
    url: '/userInfo',
    method: 'get',
    data: {
      tokenName: accessToken,
    },
  });
};

export const logout = () => {
  return request({
    url: '/logout',
    method: 'post',
  });
};

export const register = async () => {
  return request({
    url: '/register',
    method: 'post',
  });
};

你可能感兴趣的:(vue,js/jQuery,npm,ajax)