个人博客-SpringBoot+Vue3项目实战(6)- 二次封装Axios

news2025/1/6 11:00:47

目录

  • 前言
  • 新建axiosUtil.js 文件
  • 基本配置
    • 统一URL
      • `.env`文件与环境变量
      • 示例
      • 参考资料
    • 请求头
    • 超时时间
  • request 拦截器
  • response 拦截器
  • 统一Api管理
  • 测试

前言

在上文中,我们封装了统一的后端数据返回结果,有了标准化的接口数据,我们就可以针对它,在前端发送接收时,进行预处理。

通常在一个企业级或者个人开源的项目中,Axios会被二次封装。

二次封装的好处有哪些呢?

  1. 统一 url 配置
  2. 统一 api 请求
  3. request (请求)拦截器,例如:带上token等,设置请求头
  4. response (响应)拦截器,例如:统一错误处理,页面重定向等
  5. 统一处理http错误码code错误码

新建axiosUtil.js 文件

话不多说,我们直接开始吧!

创建src\utils\axiosUtil.js

这个文件就是用来封装Axios,我们想要在其他文件中使用Axios,这里我们就需要创建并抛出一个Axios实例。

import axios from 'axios'
import { ElMessage , ElNotification  } from 'element-plus'

let axiosUtil = axios.create({
})

export default axiosUtil;

接下来,我们就开始进行配置。打开http://axios-js.com/zh-cn/docs/index.html#请求配置查看Axios提供的配置项。

基本配置

统一URL

首先,我们需要配置的是统一的请求接口。我们在测试test接口时直接使用AxiosGET请求http://localhost:8080/test,这里的http://localhost:8080/就是一个统一的Url。

image-20230130135606188

let axiosUtil = axios.create({
    baseURL:'http://localhost:8080',
})

有了这个baseURL在发送post请求的时候,就不需要加上http://localhost:8080/,Axios会自动给我们加上!!!

.env文件与环境变量

但是http://localhost:8080/这个只是本地测试的接口,我们还有服务器测试接口,上线后的接口。针对不同接口,我们每次都需要修改,是一件很麻烦的事情,还好我们使用的是Vite作为的辅助开发工具。

Vite 使用 dotenv 从你的 环境目录 中的下列文件加载额外的环境变量:

.env                # 所有情况下都会加载
.env.local          # 所有情况下都会加载,但会被 git 忽略
.env.[mode]         # 只在指定模式下加载
.env.[mode].local   # 只在指定模式下加载,但会被 git 忽略

这里的模式通常包含:

  • test 测试
  • development 开发
  • production 生产
  • staging 预发布
  • 其他

也就是说我们需要在根目录下新建对应的**.env**文件

  • .env.test
  • .env.development
  • .env.production
  • .env.staging

大家打开package.json文件,会看到以下命令

 "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },

当我们在命令行执行yarn dev yarn run dev,其实是执行vite

默认情况下,dev 命令 运行在 development (开发) 模式,而 build 命令和preview命令则运行在 production (生产) 模式。

 "scripts": {
    "dev": "vite --mode development",
    "build": "vite build --mode production",
    "preview": "vite preview --mode production "
  },

在**.env**文件中,我们可以编写额外的环境变量。为了防止意外地将一些环境变量泄漏到客户端,只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码。

例如:

VITE_APP_TITLE= 个人博客
VITE_APP_BASE_API= 'http://localhost:8080'

当我们执行命令的时候,Vite 暴露环境变量到一个特殊的 import.meta.env 对象上。我们可以通过这个对象来获取编写的环境变量。

image-20230206091542335

示例

新建.env文件

VITE_APP_TITLE= 个人博客
VITE_APP_BASE_API= 'http://localhost:8080'

我们刚才说了,import.meta.env挂着我们编写的环境变量。

我们修改axiosUtils

let axiosInstance = axios.create({
   baseURL:import.meta.env.VITE_APP_BASE_API,
})

参考资料

https://cn.vitejs.dev/guide/env-and-mode.html#env-variables

请求头

我们后端支持支持什么格式的数据,这里就可以指定具体的Content-type。我们这个项目就指定json即可

import axios from 'axios'
import { ElMessage , ElNotification  } from 'element-plus'

import axios from "axios"
let axiosUtil = axios.create({
    baseURL:import.meta.env.VITE_APP_BASE_API,
    headers:{
        "Content-type":"application/json"
    }
})

超时时间

一个请求超过一段时间自动停止。

import axios from 'axios'
import { ElMessage , ElNotification  } from 'element-plus'

let axiosUtil = axios.create({
    baseURL:import.meta.env.VITE_APP_BASE_API,
    headers:{
        "Content-type":"application/json"
    }
    timeout: 10000,
})

    

request 拦截器

在请求发出之前,抽离出共同的方法。

例如 对于所有的psot请求,我们可能需要去进行序列化参数(后端要求序列化的参数),

又例如,我们发送的请求是错误的,我们要如何处理。

又又例如:我们的请求接口是需要token的,但是登录的接口不需要,此时我们在请求时就需要拦截,给除了登录接口之外的其他接口加上token。

参考官网的写法http://axios-js.com/zh-cn/docs/index.html#%E6%8B%A6%E6%88%AA%E5%99%A8

例如,我们使用的restful风格的接口,我们需要将get请求的参数拼接到URL上,那我们就可以在发送请求之前进行拼接。

// request拦截器
axiosUtil.interceptors.request.use(config => {

    // get请求映射params参数
    if (config.method === 'get' && config.params) {
        let url = config.url + '?';
        for (const propName of Object.keys(config.params)) {
            const value = config.params[propName];
            const part = encodeURIComponent(propName) + '='
            if (value !== null && typeof (value) !== "undefined") {
                if (typeof value === 'object') {
                    for (const key of Object.keys(value)) {
                        let params = propName + '[' + key + ']';
                        const subPart = encodeURIComponent(params) + '='
                        url += subPart + encodeURIComponent(value[key]) + "&";
                    }
                } else {
                    url += part + encodeURIComponent(value) + "&";
                }
            }
        }
        url = url.slice(0, -1);
        config.params = {};
        config.url = url;
    }
    return config
}, error => {
    console.log(error)
    Promise.reject(error)
})

response 拦截器

在接收到请求之后,抽离出共同的方法。

例如: 接口400怎么办,接口500怎么办!

又例如 :接收到的数据怎么办!

axiosUtil.interceptors.response.use(async res => {
    // 未设置状态码则默认成功状态
    const code = res.data.code || 200;
    // 获取错误信息
    const msg = res.data.msg 
    if (code === 500) {
        ElMessage ({
            message: msg,
            type: 'error'
        })
        return Promise.reject(new Error(msg))
    } else if (code = 401) {
        // TODO 
        console.log("重新登录,重定向登录页面")
        return Promise.reject('error')
    } else if (code !== 200) {

        ElNotification .error({
            title: msg
        })

        return Promise.reject('error')
    } else {
        return res.data
    }
}, error => {
    console.log('err' + error)
    let { message } = error;
    if (message === "Network Error") {
        message = "后端接口连接异常";
    } else if (message.includes("timeout")) {
        message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
        message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    ElMessage ({
        message: message,
        type: 'error',
        duration: 5 * 1000
    })
    return Promise.reject(error)
}
)

统一Api管理

对于同一个模块的请求我们通常是放在封装在一个文件夹里。例如这里的测试,我会新建src\api\test.js文件。

在这个文件里,编写涉及到测试的增删改查接口。

import axiosUtil from '../utils/axiosUtil.js'

class TestApi{
    create(data){
        console.log(data)
        return axiosUtil.get('/test')
    }
    delete(data){
        // 方法体内
	}
    
}
export default new TestApi();

测试

src/App.vue我们重写reqTest方法。

 import TestApi from './api/test'
 
const reqTest = () => {
  TestApi.create().then(function (response) {
      console.log(response);
    })
    .catch(function (error) {
      console.log(error);
    });
}

不启动后端,直接在前后发送请求,10000毫秒之后会弹出后端接口连接异常的消息

image-20230206100328515

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/581180.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux性能优化】你知道什么是平衡负载么

什么是平衡负载 首先大家思考一下,当你发现自己的服务变慢时,你会首先使用什么命令来排查?我通常做的第一件事,就是执行top或者uptime命令来了解系统的负载情况。比如像下面这样,我在命令行里输入top命令,…

Springboot +spring security,创建SpringSecurity项目

一.简介 搭建第一个Spring Security项目,看看如何利用Spring Security来保护Java Web项目。 二. 创建SpringSecurity项目 我们这边使用idea进行创建。 2.1创建一个基于Maven的Project项目。 2.2设置项目名称和存储位置 2.3添加项目依赖 在pom.xml文件中&#x…

LeetCode 128 最长连续序列

LeetCode 128 最长连续序列 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/longest-consecutive-sequence/description/ 博主Github:https://github.com/GDUT-Rp/LeetCode 题目: 给定一个未排…

【双系统ubuntu安装指引】配置一个顺手的深度学习环境

文章目录 前言1. 前置安装 前言 版本:ubuntu20.04 桌面版 normal安装 第一件事,切换源:换成阿里源 https://blog.csdn.net/u010092716/article/details/125832062 第二件事输入法安装,指引在这里 https://blog.csdn.net/q54434431…

JMeter性能测试:JMeter多用户并发模拟及压测结果分析

目录 JMeter设置 JMeter线程组 JMeter压测实例 View Results Tree Aggregate Report 命令行方式执行压测 jtl文件解析 JMeter多用户并发模拟 JMeter设置 多用户并发数的多少与计算机内存有关,设置 jmeter.bat (Windows) 或者 jmeter.sh (Linux):…

chapter6:SpringBoot与Docker

1. 简介 Docker是一个开源的轻量级应用容器引擎, 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到Linux机器中实现虚拟化。(沙箱机制) Docker支持将软件编译成一个镜像;然后在镜像中各种软件做好配置,将镜像…

《数据库系统概论》期末考试手写笔记汇总+考试注意事项+反思(超全整理总结!!!)

(一)期末考试手写笔记汇总 笔记内容为期末考试前整理(结合测试题PPT作业题目课本) 很多内容为纯手写,非常的全乎,预祝你期末可以考个好成绩🌹 第二章第三章(25分) (…

JS 深度克隆的实现方法

方法一:正统做法(扩展性高,推荐) function test() { this.a 1; this.b 2; } test.prototype.c 3; // 原型上的属性 const obj new test(); console.log("原对象", obj); console.log("克隆后的对象", dee…

Flume系列:案例-Flume负载均衡和故障转移

目录 Apache Hadoop生态-目录汇总-持续更新 逻辑: 2:案例需求-实现故障转移 3:实现步骤: 2.1:实现flume1.conf 2.2:实现flume2.conf - 端口4141 2.3:实现flume3.conf - 端口4142 3&#…

NIO编程总结

NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题…

【如何在Java中使用ForkJoinPool】

目录 背景1.使用ForkJoinPool的线程池2.工作窃取算法3.ForkJoinPool的主要类4.使用递归操作5.资源任务6.何时使用ForkJoinPool7.总结 背景 使用ForkJoinPool去分解计算密集型任务且且并行地执行他们以获得更好的Java应用程序的性能。 ForkJoinPool是一个功能强大的Java类&…

程序员进银行科技岗——简单总结

银行的分类 Top0—中央银行: 仅有一家,即中国人民银行。 Top1—政策性银行: 国家开发银行、中国进出口银行、中国农业发展银行 Top2—国有商业银行: 国有六大行(中国工商银行、中国农业银行、中国银行、中国建设…

【计算机网络】前后端分离,HTTP协议,网络分层结构,TCP

❤️ Author: 老九 ☕️ 个人博客:老九的CSDN博客 🙏 个人名言:不可控之事 乐观面对 😍 系列专栏: 文章目录 前后端分类HTTP协议HTTP组成HTTP的版本HTTP的请求方式HTTP请求头HTTP 响应状态码 AJAX发送请求 …

555定时器的基本原理和应用案例

前言 555定时器常用于脉冲波形的产生和整形电路中,之前在查找555定时器的原理图和基本管脚信息时,网上的内容大多含糊不清,没有讲的很详细,要么只是单一的管脚图,要么就是简单的文字解释,并且大多数缺乏基…

2023 年大厂实习前端面试题(一):跨域问题

1. 跨域 1.1 跨域问题来源 跨域问题的来源是浏览器为了请求安全而引入的基于同源策略(Same-origin policy)的安全特性。 同源策略是浏览器一个非常重要的安全策略,基于这个策略可以限制非同源的内容与当前页面进行交互,从而减少…

linux 条件变量 pthread_cond_signal

专栏内容:linux下并发编程个人主页:我的主页座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 目录 前言 简介 应用场景 与互斥量/信号量的区别 接口介绍 变量定义 初始化 等待被唤…

ROS:ROS的一些基本命令行

目录 一、打开小海龟1.1终端,启动ROS Master:1.2终端2,启动小海龟仿真器:1.3终端3,启动海龟控制节点: 二、查看系统中的计算图三、节点命令3.1查看节点下的命令rosnode3.2显示节点列表rosnode list3.3查看节…

[CISCN2023]unzip

[CISCN2023]unzip 环境搭建 1.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><form method"post" action"1.php" en…

Java 基础进阶篇(十六):多线程总结

文章目录 一、多线程概述二、多线程的创建1.1 方式一&#xff1a;继承 Thread 类1.2 方式二&#xff1a;实现 Runnable 接口匿名内部类实现方案 1.3 方式三&#xff1a;JDK 5.0新增: 实现 Callable 接口1.4 三种方式对比 二、Thread的常用方法三、线程安全与同步3.1 线程安全3.…

数据类型.

数据类型 数据类型分类 数值类型 tinyint类型 数值越界测试&#xff1a; mysql> create table tt1(num tinyint); Query OK, 0 rows affected (0.02 sec)mysql> insert into tt1 values(1); Query OK, 1 row affected (0.00 sec)mysql> insert into tt1 values(128…