Axios封装,响应拦截操作

0. 缘起

Axios封装是非常重要的一件事,我之前因为用的框架所以妹有怎么关心,既然要闪人,还是得自己思索怎么封装Axios的。

1. Axios的构成

Axios看云文档

2. Axios封装

2.1 全局头信息

axios.defaults.headers["Content-Type"] = "application/json;charset=UTF-8";

2.2 设置超时时间

axios.defaults.timeout = 1800000;

2.3 请求路由拦截

axios.interceptors.request.use(
    function (config) {
        if (sessionStorage.getItem("token")) {
            config.headers["Authorization"] = sessionStorage.getItem("token");
        }
        return config;
    },
    function (error) {
        return Promise.reject(error);
    }
);

2.4 响应拦截

// 响应拦截
axios.interceptors.response.use(
    function (response) {
        const { data, message } = response
        if (data.code !== 200) {
            Message.error({
                message: message,
                duration: 1500,
                showClose: true
            });
        }
        if (response.status === 200) {
            return Promise.resolve(response);
        } else {
            return Promise.reject(response);
        }
    },
    function (err) {
        const { status } = err.response ? err.response : { status: "" };
        if (err && err.response) {
            if (err?.response?.data?.message) {
                err.message = err?.response?.data?.message
            } else {
                switch (status) {
                    case 400:
                        err.message = "请求错误(400)";
                        break;
                    case 401:
                        err.message = "未授权,请重新登录(401)";
                        resetRouter();
                        store.commit("SET_ROUTERS", []);
                        router.push("/login");
                        break;
                    case 403:
                        err.message = "拒绝访问(403)";
                        break;
                    case 404:
                        err.message = "请求出错(404)";
                        break;
                    case 405:
                        err.message = "请求未允许(405)";
                        break;
                    case 408:
                        err.message = "请求超时(408)";
                        break;
                    case 500:
                        err.message = "服务器错误(500)";
                        break;
                    case 501:
                        err.message = "服务未实现(501)";
                        break;
                    case 502:
                        err.message = "网络错误(502)";
                        break;
                    case 503:
                        err.message = "服务不可用(503)";
                        break;
                    case 504:
                        err.message = "网络超时(504)";
                        break;
                    case 505:
                        err.message = "HTTP版本不受支持(505)";
                        break;
                    default:
                        err.message = `连接出错(${err.response.status})!`;
                }
            }
        } else {
            err.message = "连接服务器失败!";
        }
        Message.error({
            message: err.message,
            duration: 1500,
            showClose: true
        });
        return Promise.reject(err);
    }
);

2.5 封装请求方法

// 封装请求方法
export function get(url, params, baseURL = "") {
    let config = {};
    config.params = params;
    baseURL && (config.baseURL = baseURL);
    return new Promise((resolve, reject) => {
        axios
            .get(url, config)
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                resolve({ success: false, message: err.message });
            });
    });
}

export function del(url, params, baseURL = "") {
    let config = {};
    config.data = params;
    baseURL && (config.baseURL = baseURL);
    return new Promise((resolve, reject) => {
        axios
            .delete(url, config)
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                resolve({ success: false, message: err.message });
            });
    });
}

export function post(url, params, query = {}, baseURL = "") {
    let config = {};
    config.params = query;
    baseURL && (config.baseURL = baseURL);
    return new Promise((resolve, reject) => {
        axios
            .post(url, typeof params === "object" ? JSON.stringify(params) : params, config)
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                resolve({ success: false, message: err.message });
            });
    });
}

export function put(url, params, query = {}, baseURL = "") {
    let config = {};
    config.params = query;
    baseURL && (config.baseURL = baseURL);
    return new Promise((resolve, reject) => {
        axios
            .put(url, typeof params === "object" ? JSON.stringify(params) : params, config)
            .then(res => {
                resolve(res.data);
            })
            .catch(err => {
                resolve({ success: false, message: err.message });
            });
    });
}

2.6 使用该版本的请求

export function loginOut() {
    return del( '/v1/auth/logout', {}, baseUrl)
}

3. 另一种封装Axios方法

import Vue from "vue";
import axios from "axios";
import {
  contentType,
  debounce,
  invalidCode,
  loginInterception
} from "@/config";
import store from "@/store";
import QS from "qs";
import router from "@/router";
import { Message } from "element-ui";


let loadingInstance;

const baseURL = process.env.VUE_APP_BASEURL;

/**
 * @description 处理code异常
 * @param {*} code
 * @param {*} msg
 */
const handleCode = (code, msg) => {
  switch (code) {
    case invalidCode:
      Message.warning(msg || `后端接口${code}异常`, "error");
      store.dispatch("user/resetAccessToken").catch(() => {
      });
      if (loginInterception) {
        location.reload();
      }
      break;
    default:
      Message.warning(msg || `后端接口${code}异常`, "error");
      break;
  }
};

const instance = axios.create({
  baseURL,
  timeout: 1800000,
  headers: {
    "Content-Type": contentType,
  }
});

instance.interceptors.request.use(
  (config) => {
    let token = store.state.WWUser.token;
    let hasToken = store.state.WWUser.token && store.state.WWUser.token.length

    if (hasToken) {
      config.headers['Authorization'] = token;
    }
    //这里会过滤所有为空、0、false的key,如果不需要请自行注释
    // if (config.data)
    //   config.data = Vue.prototype.$baseLodash.pickBy(
    //     config.data,
    //     Vue.prototype.$baseLodash.identity
    //   );
    if (
      config.data &&
      config.headers["Content-Type"] ===
      "application/x-www-form-urlencoded;charset=UTF-8"
    )
    config.data = QS.stringify(config.data);
    if (debounce.some((item) => config.url.includes(item)))
      loadingInstance = Vue.prototype.$baseLoading();
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

instance.interceptors.response.use(
  (response) => {
    if (loadingInstance) loadingInstance.close();

    const { data, config } = response;
    const { code, message } = data;

    let successFlag = response.status;
    // 是否操作正常
    if (successFlag === 200) {
      if (response.config.responseType === 'blob') {
        return response
      } else {
        return data;
      }
    } else {
      handleCode(code, message);
      return Promise.reject(
        "请求异常拦截:" +
        JSON.stringify({ url: config.url, code, message }) || "Error"
      );
    }
  },
  (error) => {
    if (loadingInstance) loadingInstance.close();
    const { response, message } = error;
    if (error.response && error.response.data) {
      const { status, data } = response;
      handleCode(status, data.message || 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 + "异常";
      }
      Message.error(message || `后端接口未知异常`, "error");
      return Promise.reject(error);
    }
  }
);

export default instance;

3.2 使用

// Get Department Name List
export function getDepNameList () {
  return request({
    url: '/working/findByDepartment',
    method: 'post',
    baseURL
  })
}
posted @ 2022-04-06 14:41  乐盘游  阅读(355)  评论(0编辑  收藏  举报