十分钟封装一个好用的axios步骤示例

目录
  • 前言
    • 想想需要做什么
    • 通用能力
    • 一步一步添加功能实现
      • 正常请求该有的
      • 请求响应拦截器
      • 全局的loading配置
      • 统一文件下载处理
    • 使用

前言

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

想想需要做什么

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

通用能力

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

1.正常请求该有的(跨域携带cookie,token,超时设置)

2.请求响应拦截器

  • 请求成功,业务状态码200,解析result给我,我不想一层一层的去判断拿数据
  • http请求200, 业务状态码非200,说明逻辑判断这是不成功的,那就全局message提示服务端的报错
  • http请求非200, 说明http请求都有问题,也全局message提示报错
  • http请求或者业务状态码401都做注销操作

3.全局的loading配置, 默认开启,可配置关闭(由于后端的问题,经常会让前端加防抖节流或者loading不让用户在界面上疯狂乱点,行吧行吧,你们的问题前端帮你们解决,你的规矩就是规矩是吧)

4.统一文件下载处理 (不要再去各写各的下载了,你写一个,他写一个,一个项目就是这样整的跟屎一样)

一步一步添加功能实现

正常请求该有的

import axios, { AxiosInstance, AxiosRequestConfig } from "axios";
export const createAxiosByinterceptors = (
  config?: AxiosRequestConfig
): AxiosInstance => {
  const instance = axios.create({
    timeout: 1000,    //超时配置
    withCredentials: true,  //跨域携带cookie
    ...config,   // 自定义配置覆盖基本配置
  });
  return instance;
};

请求响应拦截器

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;
};

全局的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;
};

统一文件下载处理

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",
  });

完结撒花

以上就是十分钟省时又省力封装一个好用的axios步骤示例的详细内容,更多关于axios封装步骤的资料请关注我们其它相关文章!

(0)

相关推荐

  • vue如何封装Axios的get、post请求

    目录 封装Axios的get.post请求 1.封装Axios基础配置 2.封装网络请求 3.vue中使用 vue axios两种方法(封装和不封装)get请求和post请求 一.没有封装的用法 二.封中之后的用法 封装Axios的get.post请求 Axios在vue项目中用的较多,每次都要写一遍很是不方便,尤其其中的config配置项是公用的,完全可以封装一下,这样下次再用就可以直接CV了!毕竟CV大法香啊! 1.封装Axios基础配置 创建一个request.js 文件,内容如下,我把解

  • vue3实战教程之axios的封装和环境变量

    目录 axios 基本使用 配置 封装 请求时添加loading 环境变量 总结 axios axios: ajax i/o system. 一个可以同时在浏览器和node环境进行网络请求的第三方库 功能特点: 在浏览器中发送 XMLHttpRequests 请求 在 node.js 中发送 http请求 支持 Promise API 拦截请求和响应 转换请求和响应数据 等等 基本使用 get请求 // 导入的axios是一个实例对象 import axios from 'axios' // a

  • react使用axios进行api网络请求的封装方法详解

    目录 前言 准备工作 开始封装axios config.js request.js 进行请求 总结 前言 最近写react项目使用到axios进行请求封装,在这里记录一下,希望可以帮助到初学的小伙伴 准备工作 进行请求需要使用axios,所以要先确定你已经安装完成了axios,查看package.json文件 如果没有,请先安装axios npm install axios 开始封装axios 首先在src目录下新建axios文件夹,这里我们新建两个文件,分别是config.js和request

  • vue项目中axios的封装请求

    目录 一.简介 二.封装后 1.封装步骤 2.封装目标 3.使用新的axios封装API 4.使用封装后的axios 一.简介 axios 是一个轻量的HTTP客户端,它基于 XMLHttpRequest 服务来执行 HTTP 请求,支持丰富的配置,支持 Promise,支持浏览器端和 Node.js 端.自Vue2.0起,尤大大宣布取消对vue-resource 的官方推荐,转而推荐 axios.现在 axios 已经成为大部分 Vue 开发者的首选.( 如果你还不熟悉 axios,可以在这里

  • Vue3引入axios封装接口的两种方法实例

    目录 第一种 1.安装 2.新建一个http.js文件 3.使用 第二种 1.安装 2.新建 3.http.js 4.request.js 总结 第一种 1.安装 npm install axios -S 2.新建一个http.js文件 import axios from "axios"; import qs from "qs"; import { Dialog, Toast } from "vant"; // axios.defaults.ba

  • Axios代理配置及封装响应拦截处理方式

    目录 Axios代理配置及响应拦截处理 代理配置 响应内容拦截处理 Axios的proxy代理配置解析 Axios代理配置及响应拦截处理 Axios是vue官方推荐的异步处理方案,所以在几个vue的项目里,都用到了,所以这里写一下Axios的代理配置和响应拦截处理 代理配置 代理主要是为了解决跨域问题,但是现在常规解决跨域的方式,就是让后端配置响应头,使用cors方式跨域前端基本不需要任何处理. 但是有时候后端比较懒,就需要前端通过代理请求完成跨域,其实就是相当于在本地开了一个服务器,通过服务器

  • 十分钟封装一个好用的axios步骤示例

    目录 前言 想想需要做什么 通用能力 一步一步添加功能实现 正常请求该有的 请求响应拦截器 全局的loading配置 统一文件下载处理 使用 前言 项目启动会议上,大家各种出排期,各种出方案,大多数人的焦点都放在后端技术方案上,感情大家好像都觉得前期准备工作前端没啥好做的,不都有现成的脚手架吗?别人不都帮你做好了吗?我丢....你说的好像不是没有道理,但是你真的用过官方的脚手架吗,除了帮我生成项目目录和打包编译之类的配置,还是有些框架层面的东西要我自己做的好吧.我不管我不管,你们都有启动准备排期

  • 2分钟实现一个Vue实时直播系统的示例代码

    前言 我们在不敲代码的时候可能会去看游戏直播,那么是前台怎么实现的呢?下面我们来讲一下. 第一步,购买云直播服务 首先,你必须去阿里云或者腾讯云注册一个直播服务.也花不了几个钱,练手的话,几十块钱就够了. 这里我拿阿里云举例,购买完了,配置好推流域名跟播流域名,下面我们将进行地址生成.记住下面生成的地址,下面会用到. 第二步,下载本地推流工具 https://obsproject.com/ 第三步,设置OBS 在第一步中图片底部有推流地址,需要注意,分为两部分填入下方图所示. 在AppName字

  • 基于vue-upload-component封装一个图片上传组件的示例

    需求分析 业务要求,需要一个图片上传控件,需满足 多图上传 点击预览 图片前端压缩 支持初始化数据 相关功能及资源分析 基本功能 先到https://www.npmjs.com/search?q=vue+upload上搜索有关上传的控件,没有完全满足需求的组件,过滤后找到 vue-upload-component 组件,功能基本都有,自定义也比较灵活,就以以此进行二次开发. 预览 因为项目是基于 vant 做的,本身就提供了 ImagePreview 的预览组件,使用起来也简单,如果业务需求需要

  • Java十分钟精通类 封装 继承

    目录 什么是类成员 什么是实例变量 那么实例变量和类变量的区别呢? 那么类方法和实例方法的区别? static关键字 static成员方法: static用处: 封装: 封装的概念 封装的分类 封装的使用 继承: 什么是继承 继承的使用: 方法重写的规则: super关键字: 什么是类成员 使用static修饰的成员方法和成员变量称为类成员 使用static修饰的成员变量叫做类变量 使用static修饰的成员方法叫做类方法 什么是实例变量 未使用static修饰的成员方法和成员变量称为实例成员

  • 十分钟上手正则表达式 下篇

    目录 一.正则表达式常用符号 1.1 问号[?] 1.2 加号[+] 1.3 花括号{} 1.4 管道符号[|] 1.5 小括号() 二.正则表达式实战示例 示例1: 示例2: 前面,我们就正则表达式一些常用的基本方法做了详细的介绍,本篇会讲解一些拓展性的知识,主要的就是常见的ERE模式符号以及shell脚本中常见的一些正则表达式例子. 快速学习正则表达式,不用死记硬背,示例让你通透(上篇) 一.正则表达式常用符号 本章示例着重于在gawk程序脚本中的较常见的ERE模式符号. 1.1 问号[?]

  • Java十分钟精通包装类的使用与操作

    包装类 何为包装类? 基本类型包装类的概述: 将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据 包装类是将基本数据类型的值包装为Java中的对象,Java语言为8种基本数据类型分别提供了包装类 首先看一下八大数据类型的包装类: 包装类型出现的原因: 因为Java是一个面向对象的语言,基本类型并不具有对象的性质,为了与其他对象"接轨"就出现了包装类型,它相当于将基本类型"包装起来",使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本

  • Java十分钟精通内部类的使用

    内部类: 其实内部类顾名思义,就是类中类,一个类里面还有一个类. 内部类分为四种: 普通内部类 静态内部类 方法内部类 匿名内部类 我们一一去了解一下~~ A.普通内部类: 我们先通过代码去了解一下: package InternalClass; /** * 内部类 */ public class Car { public int a = 10; public int b = 20; //外部类的方法 public void method() { System.out.println("我是外部

  • Java十分钟精通多态与抽象类的使用与原理

    我们知道Java的三大特性:封装.继承.多态.前两个之前在Java入门(六)已经讲到,现在来讲多态这个特性. 什么是多态? 多态顾名思义即为多种形态的意思 Java中多态的含义: 发送消息给某个对象,让这个对象自行决定采用哪种行为响应这个消息 子类对象的引用赋值给父类引用变量来实现动态的方法调用 Java中形成多态的前提: 继承 父类方法的重写 向上转型 我对多态的解释: 比如我们,是人,也是学生,也是年轻人,我可以用人的身份去做事情,也可以用学生的身份去买学生票,也可以用年轻人的身份做公益,这

  • Python编程django实现同一个ip十分钟内只能注册一次

    很多小伙伴都会有这样的问题,说一个ip地址十分钟内之内注册一次,用来防止用户来重复注册带来不必要的麻烦 逻辑: 取ip,在数据库找ip是否存在,存在判断当前时间和ip上次访问时间之差,小于600不能注册,到登录界面,大于600可以注册,设计一个数据库来存储这个ip地址和访问时间, class Ip(models.Model): ip=models.CharField(max_length=20) time=models.DateTimeField() class Meta: verbose_na

  • django实现登录时候输入密码错误5次锁定用户十分钟

    在学习django的时候,想要实现登录失败后,进行用户锁定,切记录锁定时间,在网上找了很多资料,但是都感觉不是那么靠谱,于是乎,我开始了我的设计,其实我一开始想要借助redis呢,但是想要先开发一个简单的,后续在拆分后,然后在去进行拆分, 这样也是很接近我们在真实的开发中所遇到问题. 我的思路是: 输入账号密码>是否已经登录>提示已经登录 输入账号密码>错误次数少于6次>校验密码>登录成功,记录登录时间,错误次数清空,记录登录状态 输入账号密码>错误大于六次>提示

随机推荐