十分钟封装一个好用的axios,省时又省力他不香吗

简介: 十分钟封装一个好用的axios,省时又省力他不香吗

前言

项目启动会议上,大家各种出排期,各种出方案,大多数人的焦点都放在后端技术方案上,感情大家好像都觉得前期准备工作前端没啥好做的,不都有现成的脚手架吗?别人不都帮你做好了吗?💉💉我丢。。。。你说的好像不是没有道理,但是你真的用过官方的脚手架吗,除了帮我生成项目目录和打包编译之类的配置,还是有些框架层面的东西要我自己做的好吧。我不管我不管,你们都有启动准备排期,我他喵的也要!!🔫

想想需要做什么

我争取到了一周的准备(划水摸鱼)时间,主要还是后端的大佬们牛批会争取啊,我只能和他们持平了,啊哈哈哈。先用vue-cli生成一个project吧,想想做些什么,想到以前的做项目通用请求能力封装这一块前期做的不太好,导致后面写起来一堆冗余代码,着实恶心到我了。那我必须前期把这个整整🙌🙌

通用能力

列一下我想要这个通用请求能达到什么样的效果

  1. 正常请求该有的(跨域携带cookie,token,超时设置)
  2. 请求响应拦截器
  • 请求成功,业务状态码200,解析result给我,我不想一层一层的去判断拿数据
  • http请求200, 业务状态码非200,说明逻辑判断这是不成功的,那就全局message提示服务端的报错
  • http请求非200, 说明http请求都有问题,也全局message提示报错
  • http请求或者业务状态码401都做注销操作
  1. 全局的loading配置, 默认开启,可配置关闭(由于后端的问题,经常会让前端加防抖节流或者loading不让用户在界面上疯狂乱点,行吧行吧,你们的问题前端帮你们解决,你的规矩就是规矩是吧🍜)
  2. 统一文件下载处理 (不要再去各写各的下载了,你写一个,他写一个,一个项目就是这样整的跟屎一样)

一步一步添加功能实现

  1. 正常请求该有的
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
export const createAxiosByinterceptors = (
  config?: AxiosRequestConfig
): AxiosInstance => {
  const instance = axios.create({
    timeout: 1000,    //超时配置
    withCredentials: true,  //跨域携带cookie
    ...config,   // 自定义配置覆盖基本配置
  });
  return instance;
};
  1. 请求响应拦截器
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { Message } from "element-ui";
import { jumpLogin } from "@/utils";
export const createAxiosByinterceptors = (
  config?: AxiosRequestConfig
): AxiosInstance => {
  const instance = axios.create({
    timeout: 1000,    //超时配置
    withCredentials: true,  //跨域携带cookie
    ...config,   // 自定义配置覆盖基本配置
  });
  // 添加请求拦截器
  instance.interceptors.request.use(
    function (config: any) {
      // 在发送请求之前做些什么
      console.log("config:", config);
      // config.headers.Authorization = vm.$Cookies.get("vue_admin_token");
      return config;
    },
    function (error) {
      // 对请求错误做些什么
      return Promise.reject(error);
    }
  );
  // 添加响应拦截器
  instance.interceptors.response.use(
    function (response) {
      // 对响应数据做点什么
      console.log("response:", response);
      const { code, data, message } = response.data;
      if (code === 200) return data;
      else if (code === 401) {
         jumpLogin();
      } else {
         Message.error(message);
         return Promise.reject(response.data);
      }
    },
    function (error) {
      // 对响应错误做点什么
      console.log("error-response:", error.response);
      console.log("error-config:", error.config);
      console.log("error-request:", error.request);
      if (error.response) {
        if (error.response.status === 401) {
          jumpLogin();
        }
      }
      Message.error(error?.response?.data?.message || "服务端异常");
      return Promise.reject(error);
    }
  );
  return instance;
};
  1. 全局的loading配置
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { Message } from "element-ui";
import { jumpLogin } from "@/utils";
import { Loading } from "element-ui";
import { ElLoadingComponent } from "element-ui/types/loading";
// import vm from "@/main";
let loadingInstance: ElLoadingComponent | null = null;
let requestNum = 0;
const addLoading = () => {
  // 增加loading 如果pending请求数量等于1,弹出loading, 防止重复弹出
  requestNum++;
  if (requestNum == 1) {
    loadingInstance = Loading.service({
      text: "正在努力加载中....",
      background: "rgba(0, 0, 0, 0)",
    });
  }
};
const cancelLoading = () => {
  // 取消loading 如果pending请求数量等于0,关闭loading
  requestNum--;
  if (requestNum === 0) loadingInstance?.close();
};
export const createAxiosByinterceptors = (
  config?: AxiosRequestConfig
): AxiosInstance => {
  const instance = axios.create({
    timeout: 1000,    //超时配置
    withCredentials: true,  //跨域携带cookie
    ...config,   // 自定义配置覆盖基本配置
  });
  // 添加请求拦截器
  instance.interceptors.request.use(
    function (config: any) {
      // 在发送请求之前做些什么
      const { loading = true } = config;
      console.log("config:", config);
      // config.headers.Authorization = vm.$Cookies.get("vue_admin_token");
      if (loading) addLoading();
      return config;
    },
    function (error) {
      // 对请求错误做些什么
      return Promise.reject(error);
    }
  );
  // 添加响应拦截器
  instance.interceptors.response.use(
    function (response) {
      // 对响应数据做点什么
      console.log("response:", response);
      const { loading = true } = response.config;
      if (loading) cancelLoading();
      const { code, data, message } = response.data;
      if (code === 200) return data;
      else if (code === 401) {
        jumpLogin();
      } else {
         Message.error(message);
         return Promise.reject(response.data);
      }
    },
    function (error) {
      // 对响应错误做点什么
      console.log("error-response:", error.response);
      console.log("error-config:", error.config);
      console.log("error-request:", error.request);
      const { loading = true } = error.config;
      if (loading) cancelLoading();
      if (error.response) {
        if (error.response.status === 401) {
          jumpLogin();
        }
      }
      Message.error(error?.response?.data?.message || "服务端异常");
      return Promise.reject(error);
    }
  );
  return instance;
};
  1. 统一文件下载处理
import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
import { Message } from "element-ui";
import { jumpLogin, downloadFile } from "@/utils";
import { Loading } from "element-ui";
import { ElLoadingComponent } from "element-ui/types/loading";
// import vm from "@/main";
let loadingInstance: ElLoadingComponent | null = null;
let requestNum = 0;
const addLoading = () => {
  // 增加loading 如果pending请求数量等于1,弹出loading, 防止重复弹出
  requestNum++;
  if (requestNum == 1) {
    loadingInstance = Loading.service({
      text: "正在努力加载中....",
      background: "rgba(0, 0, 0, 0)",
    });
  }
};
const cancelLoading = () => {
  // 取消loading 如果pending请求数量等于0,关闭loading
  requestNum--;
  if (requestNum === 0) loadingInstance?.close();
};
export const createAxiosByinterceptors = (
  config?: AxiosRequestConfig
): AxiosInstance => {
  const instance = axios.create({
    timeout: 1000,    //超时配置
    withCredentials: true,  //跨域携带cookie
    ...config,   // 自定义配置覆盖基本配置
  });
  // 添加请求拦截器
  instance.interceptors.request.use(
    function (config: any) {
      // 在发送请求之前做些什么
      const { loading = true } = config;
      console.log("config:", config);
      // config.headers.Authorization = vm.$Cookies.get("vue_admin_token");
      if (loading) addLoading();
      return config;
    },
    function (error) {
      // 对请求错误做些什么
      return Promise.reject(error);
    }
  );
  // 添加响应拦截器
  instance.interceptors.response.use(
    function (response) {
      // 对响应数据做点什么
      console.log("response:", response);
      const { loading = true } = response.config;
      if (loading) cancelLoading();
      const { code, data, message } = response.data;
      // config设置responseType为blob 处理文件下载
      if (response.data instanceof Blob) {
        return downloadFile(response);
      } else {
        if (code === 200) return data;
        else if (code === 401) {
          jumpLogin();
        } else {
          Message.error(message);
          return Promise.reject(response.data);
        }
      }
    },
    function (error) {
      // 对响应错误做点什么
      console.log("error-response:", error.response);
      console.log("error-config:", error.config);
      console.log("error-request:", error.request);
      const { loading = true } = error.config;
      if (loading) cancelLoading();
      if (error.response) {
        if (error.response.status === 401) {
          jumpLogin();
        }
      }
      Message.error(error?.response?.data?.message || "服务端异常");
      return Promise.reject(error);
    }
  );
  return instance;
};
src/utils/index.ts
import { Message } from "element-ui";
import { AxiosResponse } from "axios";
import vm from "@/main";
/**
 *   跳转登录
 */
export const jumpLogin = () => {
  vm.$Cookies.remove("vue_admin_token");
  vm.$router.push(`/login?redirect=${encodeURIComponent(vm.$route.fullPath)}`);
};
/**
 * 下载文件
 * @param response
 * @returns
 */
export const downloadFile = (response: AxiosResponse) => {
  console.log("response.data.type:", response.data.type);
  return new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.onload = function () {
      try {
        console.log("result:", this.result);
        const jsonData = JSON.parse((this as any).result); // 成功 说明是普通对象数据
        if (jsonData?.code !== 200) {
          Message.error(jsonData?.message ?? "请求失败");
          reject(jsonData);
        }
      } catch (err) {
        // 解析成对象失败,说明是正常的文件流
        const blob = new Blob([response.data]);
        // 本地保存文件
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement("a");
        link.href = url;
        const filename = response?.headers?.["content-disposition"]
          ?.split("filename*=")?.[1]
          ?.substr(7);
        link.setAttribute("download", decodeURI(filename));
        document.body.appendChild(link);
        link.click();
        resolve(response.data);
      }
    };
    fileReader.readAsText(response.data);
  });
};

使用

import { createAxiosByinterceptors } from "@/api/request";
const request = createAxiosByinterceptors({
  baseURL: localhost:7007,
});
//lodaing配置
export const appList = (params: any): Promise<any> =>
  request.get("/app", { params, loading: true }); // 不需要默认的全局loading效果可配置loading为false关闭 loading默认为true
// 文件下载
export const exportGoods = (data: any) =>
  request.post("/export", data, {
    responseType: "blob",
  });

 

总结给大家一个实用面试题库

1、前端面试题库 (面试必备)            推荐:★★★★★

地址:前端面试题库

相关文章
|
1月前
|
JavaScript
vue封装axios(用interceptors封装)
vue封装axios(用interceptors封装)
13 0
|
3月前
|
前端开发
Axios request 封装技巧:提升代码复用和效率的步骤
在开发中,为了提高效率,通常对 Axios 进行封装,简化了请求的发送和对响应的处理。同时,统一错误处理机制有助于维护代码的清晰和一致性。本文介绍了一些高效封装 Axios 请求的方法。
Axios request 封装技巧:提升代码复用和效率的步骤
|
4月前
|
存储 JSON 前端开发
封装axios的两种方式
封装axios的两种方式
|
17天前
|
缓存 前端开发 JavaScript
前端vue3分享——项目封装axios、vite使用env环境变量
前端vue3分享——项目封装axios、vite使用env环境变量
19 0
|
19天前
|
存储 算法 JavaScript
< 今日小技巧:Axios封装,接口请求增加防抖功能 >
今天这篇文章,主要是讲述对axios封装的请求,由于部分请求可能存在延时的情况。使得接口可能存在会被持续点击(即:接口未响应的时间内,被持续请求),导致重复请求的问题,容易降低前后端服务的性能!故提出给axios封装的配置里面,新增一个防抖函数,用来限制全局请求的防抖。
< 今日小技巧:Axios封装,接口请求增加防抖功能 >
|
20天前
|
JSON JavaScript 前端开发
< 每日份知识快餐:axios是什么?如何在Vue中 封装 axios ? >
本文介绍了前端开发中常用的HTTP客户端库Axios,它基于Promise,支持浏览器和Node.js,特点是功能强大、支持Promise API和并发请求,并能拦截请求和响应。文章强调了理解Axios的内部原理和优化使用的重要性,不仅讲解了基本的安装、导入和使用方法,还阐述了为何选择Axios,包括其丰富的配置选项和良好的浏览器支持。此外,文章探讨了封装Axios的必要性,以减少重复代码和提高代码维护性,并给出了设置接口请求前缀、请求头、超时时间以及封装请求方法和拦截器的示例。通过封装,开发者可以更高效地管理和使用Axios,适应不同项目需求。
|
26天前
axios封装和配置
axios封装和配置
19 0
|
2月前
04_装饰器封装axios_get请求
04_装饰器封装axios_get请求
30 0
|
2月前
|
前端开发
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
|
3月前
|
资源调度 JavaScript API