封装的详细的接口请求http.js

import axios from "axios";
import { ElMessage } from "element-plus";
import { startLoading, endLoading } from "@/utils/loading";
import {
  SET_TOKEN,
  GET_TOKEN,
  SET_USERINFO,
  GET_LANG,
} from "@/utils/localStorage.js";
import { checkStatus } from "./checkStatus";
import router from "../router";
const NETWORK_ERROR = "网络错误, 请稍后再试";
const LoadingInstance = {
  _count: 0,
};
function http(
  axioxConfig,
  customOptions,
  loadingOptions = { text: "loading…" }
) {
  // 基础配置
  const service = axios.create({
    // baseURL: window.location.protocol + import.meta.env.VITE_SERVE,
    baseURL: import.meta.env.VITE_SERVE,
    timeout: 200000,
    useTokenAuthorization: true,
    headers: {
      "Content-Type": "application/json",
      "Accept-Language": GET_LANG() || "zh_CN",
    },
  });

  // 自定义配置
  let custom_options = Object.assign(
    {
      repeat_request_cancel: true, // 是否开启取消重复请求, 默认为 true
      loading: true, // 是否开启loading层效果, 默认为true
      error_message_show: true, // 是否开启 处理错误状态码
      reduct_data_format: true, // 是否开启简洁的数据结构响应, 默认为false
      code_message_show: true, // 是否开启code不为200时的信息提示, 默认为true
      is_token: true, // 是否要token
      delet_invalid_data: false, //是否去除data中无效的参数。例如‘’,默认不去除
    },
    customOptions
  );

  // 请求拦截器
  service.interceptors.request.use(
    (config) => {
      const token = GET_TOKEN();
      const isToken = custom_options?.is_token;

      // 自动携带token
      if (token && typeof window !== "undefined") {
        if (isToken) {
          config.headers.Authorization = `Bearer ${token}`;
        }
      }

      // 取消重复请求代码
      removePending(config);
      custom_options.repeat_request_cancel && addPending(config);

      // 创建loading实例
      if (custom_options.loading) {
        LoadingInstance._count++;
        if (LoadingInstance._count === 1) {
          startLoading(loadingOptions.text);
        }
      }
      if (custom_options.delet_invalid_data) {
        //去除请求数据无效属性
        if (config.data) {
          for (let k in config.data) {
            if (
              config.data[k] === undefined ||
              config.data[k] === "" ||
              config.data[k] === null
            ) {
              delete config.data[k];
            }
          }
        }
      }

      return config;
    },
    (error) => {
      return Promise.reject(error);
    }
  );

  // 返回拦截器
  service.interceptors.response.use(
    (response) => {
      // 关闭loading
      custom_options.loading && closeLoading(custom_options);
      let fileName = "";
      if (response.headers["content-disposition"]) {
        const fileStr = response.headers["content-disposition"];
        // .split("=")[1]
        // .slice(7);
        fileName = decodeURI(fileStr);
        if (fileName.includes("utf-8")) {
          fileName = fileName.split("utf-8")[1].slice(2).replace("%2C", " ");
        } else {
          fileName = fileName.split("=")[1];
        }

        sessionStorage.setItem("excel-name", fileName);
      }
      // 取消重复请求代码
      removePending(response.config, custom_options);

      if (response.config.responseType == "blob") {
        return custom_options.reduct_data_format ? response.data : response;
      }
      const { code, msg } = response?.data;
      const message = msg || NETWORK_ERROR; // 获取错误信息
      if (
        custom_options.code_message_show &&
        response.data &&
        response.data.code !== 200
      ) {
        ElMessage.closeAll();
        // 1002000009 用户密码输入错误次数太多,账户锁定5分钟,请稍后再试
        if (
          code === 1002000004 || //调出图形验证码
          code === 1002000008 ||
          code === 1002030004 || //文件不存在
          code === 51013 //远程抄表超时处理
        ) {
          return custom_options.reduct_data_format ? response.data : response;
        }
        ElMessage.error(msg);
        if (code === 401) {
          // 退出登录
          SET_TOKEN("");
          SET_USERINFO({});
          router.replace("/log/login");
        }
        // code不等于200, 页面具体逻辑就不执行了

        return Promise.reject(message);
      }
      if (code === 200) {
        return custom_options.reduct_data_format ? response.data : response;
      }
    },
    (error) => {
      custom_options.loading && closeLoading(custom_options);
      error.config && removePending(error.config);
      // 处理错误状态码
      custom_options.error_message_show && checkStatus(error?.response?.status);
      return Promise.reject(error);
    }
  );
  return service(axioxConfig);
}

const pendingMap = new Map();
// 生成每个请求唯一的键
function getPendingKey(config) {
  let { url, method, params, data } = config;
  if (typeof data === "string") data = JSON.parse(data); // response里面返回的config.data是个字符串对象
  return [url, method, JSON.stringify(params), JSON.stringify(data)].join("&");
}
// 储存每个请求唯一值,也就是cancel()方法,用于取消请求
function addPending(config) {
  const pendingKey = getPendingKey(config);
  config.cancelToken =
    config?.cancelToken ||
    new axios.CancelToken((cancel) => {
      if (!pendingMap.has(pendingKey)) {
        pendingMap.set(pendingKey, cancel);
      }
    });
}
// 取消重复请求并删除队列
function removePending(config, custom_options) {
  custom_options?.loading && closeLoading(custom_options);
  const pendingKey = getPendingKey(config);
  if (pendingMap.has(pendingKey)) {
    const cancelToken = pendingMap.get(pendingKey);
    cancelToken(pendingKey);
    pendingMap.delete(pendingKey);
  }
}

function closeLoading(_options) {
  if (_options.loading && LoadingInstance._count > 0) LoadingInstance._count--;
  if (LoadingInstance._count === 0) {
    setTimeout(() => {
      endLoading();
    }, 500);
  }
}

export default http;

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值