Axios封装以及添加拦截器

     在前端开发中,http请求层的封装可以极大提升代码的复用性和可维护性,本文将完整的用axios封装接口请求,配置请求与响应拦截器,封装统一的请求方法全过程。

   封装的目的和思路

        在项目直接用axios发送请求当然没问题,但是如果不做封装,每个请求都需要手动处理token,错误提示等逻辑,容易重复,缺乏统一的loading处理逻辑,不同组件可以用不一致的方式调用axios增加维护成本。业务错误,比如登录失败权限不足不集中处理用户体验差。

        所以我们统一封装是为了实现这些目标。

        1.封装Axios实例+设置baseURL和超时。

        2.添加请求拦截器:自动加token显示Loading

        3.添加响应拦截器 统一处理错误隐藏loading

        4 暴露统一的get/post等请求方法

        5.支持类型推导(泛型)

      step1:安装Axios

        npm install axios 

     step2:创建Axios实例并且封装基础配置

// api/request.ts
import axios, { AxiosError } from 'axios'
import { message } from 'antd'
import { showLoading, hideLoading } from './loading'const instance = axios.create({baseURL: '/api',                 // 接口统一前缀timeout: 8000,                   // 超时时间timeoutErrorMessage: '请求超时,请稍后再试',withCredentials: false,          // 是否携带 Cookie
})

为什么要用 axios.create?

可以创建多个实例,分别管理不同的 baseURL(如主站与后台接口)。

不影响全局 axios,互不干扰。

step3:请求拦截器

instance.interceptors.request.use((config) => {showLoading()const token = localStorage.getItem('token')if (token) {config.headers.Authorization = 'Token::' + token}return { ...config }},(error: AxiosError) => {return Promise.reject(error)}
)

 请求拦截器做了什么?

        1.请求前显示 loading(配合 Ant Design 的 Spin)

        2.自动从 localStorage 中读取 token,统一加入到请求头中 

        3.你也可以添加其他自定义 headers,例如用户 ID、语言偏好等

step4:响应拦截器--统一 错误处理以及成功返回data

        

instance.interceptors.response.use((response) => {hideLoading()const data = response.dataif (data.code === 500001) {// 登录失效message.error(data.msg || '身份已过期,请重新登录')localStorage.removeItem('token')return Promise.reject(data)} else if (data.code !== 0) {// 业务错误message.error(data.msg || '请求错误,请稍后重试')return Promise.reject(data)}return data.data // 请求成功,返回业务数据},(error: AxiosError) => {hideLoading()message.error(error.message || '服务器异常,请稍后重试')return Promise.reject(error)}
)

  

        拦截器可能有人不理解概念。这里把概念放在这里。

        axios.interceptors.request.use 是 Axios 提供的 API,用来设置请求发出前的统一处理逻辑。

它接收两个回调函数,第一个是处理请求体 config 的,我们通常在这里加上 token、显示 loading,处理完之后必须返回 config 否则请求会被中断。

        第二个是请求配置阶段发生错误时的处理函数,比如拦截器中抛出异常,这个函数里我们一般把错误通过 Promise.reject 抛出去,供 .catch 捕获使用。

        Axios 的响应拦截器也接收两个回调函数,第一个是响应成功时调用,它的参数是 response,从中我们可以提取 response.data,然后判断自定义的 code 字段,来决定是 token 过期、业务出错还是成功。如果 token 过期或失败,会弹出错误提示,并通过 Promise.reject 抛出错误。

        第二个回调函数是响应失败(如网络错误、404、500)时触发的,我们可以统一显示“服务器异常”等提示,也用 Promise.reject 抛出错误,供组件用 .catch() 捕获。

    后端返回的 data 结构通常如下:

{

"code": 0,

"msg": "成功",

"data": { "userInfo": { ... } }

}

         然后我们就可以明显看到我们请求拦截器实际上就是config这个请求体在发送之前我们去加一些逻辑去处理我们的config请求体。比如头部加上Authorization属性值为token把我们的token加上去。还有第二个回调函数,就是把错误作为Promise实例的reject(error)扔出去,这样我们组件可以用.catch捕捉。

        响应拦截器同理,response就是我们的响应体。我们响应体在到组件接收之前我们对响应体做一些处理,比如我们不需要响应体,我们只是想要里面的data.data那么成功就返回data.data如果token过期了久调用message这是个组件然后.error显示错误比如token过期了。总之只要有响应体一定会返回data给到我们的组件。如果响应拦截的时候就发现报错了那么就reject扔出error组件.catch捕获。

step5:封装统一请求方法(泛型)

export default {get<T>(url: string, params?: object): Promise<T> {return instance.get(url, { params })},post<T>(url: string, params?: object): Promise<T> {return instance.post(url, params)},// 后续可添加 put、delete 等
}

     

为什么要用泛型 <T>

  • 调用接口时能获得接口返回值的类型提示,增强类型安全

  • 调用时直接写 const res = await api.get<YourType>(...)

step6:如何使用封装后的请求

// api/user.ts
import request from './request'export const getUserInfo = () => {return request.get<{ name: string; age: number }>('/user/info')
}

        通过引入对象的形式直接调用里面的方法就可以了,然后声明泛型也就是我们如果需要返回值的话声明返回值的类型。然后后面是传过去的url访问的接口。实际上访问的地址是baseUrl+我们传过去的url。

        总结

         

         

 

 

 

 

        

 

 

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

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

相关文章

C语言中奇技淫巧04-仅对指定函数启用编译优化

相信很多人使用GCC编译代码时&#xff0c;都会接触到gcc -O0/1/2/3/s&#xff0c;知道它可以对工程进行全局优化。 事实上&#xff0c;除了全局优化外&#xff0c;使用GCC扩展方式&#xff0c;我们还可以仅对部分关键函数实施差异化编译优化。 在GCC编译器中&#xff0c;attrib…

HTML Style 对象深度解析:从基础到高级应用

一、Style 对象的核心概念定义与作用 Style 对象是 HTML DOM 中用于操作元素内联样式的接口&#xff0c;通过 element.style 访问。它允许动态修改元素的 CSS 属性&#xff0c;但仅能直接影响内联样式&#xff08;即通过 style 属性直接写在标签中的样式&#xff09;。与外部样…

【C++】定义常量

在 C 中&#xff0c;有两种简单的定义常量的方式&#xff1a; 使用 #define 预处理器。使用 const 关键字。 #define 预处理器 #include <iostream> using namespace std;#define LENGTH 10 #define WIDTH 5 #define NEWLINE \nint main() {int area; area LENGTH …

基于遗传算法的多无人车协同侦察与安全保护策略优化

基于遗传算法的多无人车协同侦察与安全保护策略优化 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff0c;觉得好请收藏。点击跳转到网站。 1. 引言 1.1 研究背景与意义 随着无人系统技术的快速发…

python面向对象编程详解

面向对象编程&#xff08;OOP&#xff09;是一种以对象为核心的编程范式。Python全面支持OOP&#xff0c;主要包含以下核心概念&#xff1a;一、类与对象1.类(Class)类是创建对象的模板或蓝图&#xff0c;它定义了对象的属性和方法。class Dog:# 类属性&#xff08;所有实例共享…

快速入门Socket编程——封装一套便捷的Socket编程——导论

快速入门Socket编程——封装一套便捷的Socket编程——导论 前言 ​ 这里是笔者打算做的Socket编程的第二部分&#xff0c;也就是核心的讨论我们Socket编程本身。 导论 ​ 我们知道&#xff0c;一个经典的服务器套接字的处理流程是如下的&#xff1a; 创建一个指定传输层和网络层…

【Mermaid 离线工具】Mermaid 流程图生成器 - 高清PNG输出,一键生成专业级流程图!

文章目录 Mermaid 流程图生成器(离线版本):高效绘图,离线也能玩转专业可视化 一、Mermaid:文本绘图的 “魔法语法” 二、离线版生成器:功能与优势解析 (一)离线可用,场景更灵活 (二)操作流程:简单五步,产出专业图表 (三)界面设计:简洁直观,降低使用门槛 三、应…

haproxy原理及实战部署

一、负载均衡 负载均衡是网络架构和分布式系统中至关重要的技术&#xff0c;其核心作用是将大量的并发请求或数据流量合理分配到多个服务器&#xff08;或其他资源节点&#xff09;上&#xff0c;从而解决单节点压力过大、资源利用率低、系统稳定性差等问题。 作用1. 提高系统吞…

jwt 在net9.0中做身份认证

一、新建net9.0项目WebApplication1&#xff0c;安装包 <ItemGroup><PackageReference Include"Microsoft.AspNetCore.Authentication.JwtBearer" Version"9.0.7" /><PackageReference Include"Swashbuckle.AspNetCore" Version&…

【机器学习深度学习】微调能改变模型“智商”吗?——模型能力与知识的本质解析

目录 前言 一、模型的“知识”与“能力”&#xff1a;两种不同的智能 第一种&#xff1a;浅层知识&#xff08;记忆 模式识别&#xff09; 第二种&#xff1a;深层能力&#xff08;推理 理解&#xff09; 二、微调&#xff1a;改变的是“经历”&#xff0c;不是“天赋”…

oracle数据库表空间碎片整理

oracle数据库表空间碎片整理 表空间碎片情况检查 表空间碎片问题处理 收缩表 表空间手动整理 exp/imp导出再导入 移动表到新的表空间 表空间碎片情况检查 对比表实际使用空间和数据文件占用空间: --实际数据占用空间 select tablespace_name,round(sum(bytes/1024/1024/1024…

为什么需要可重入锁

在黑马点评项目实战中&#xff0c;提到了可重入锁&#xff0c;然后我想到了是不是不同业务在同一线程内反复获取同一把锁。本文来讨论一下为什么锁需要可重入。一、可重入锁的核心&#xff1a;“同一线程多次获取同一把锁”​​可重入&#xff08;Reentrant&#xff09;​​ 的…

【AI】联网模式

【AI】联网模式 文章目录【AI】联网模式1. 简介2. 接入步骤2.1 引入依赖2.2 方法构建2.3 接口构建1. 简介 在使用联网模式之前&#xff0c;我们如果问起ai一些最近网络上流传的一些东西&#xff0c;它可能并不能准确的给你描述出来&#xff0c;因为它的知识库更新时间可能停留…

第10篇:实战验收篇

&#x1f50d; 实战演练&#xff1a;多条件房源查询 需求描述 查找一套符合以下条件的房子&#xff1a; 预算&#xff1a;2000–3000元区域&#xff1a;天河区户型&#xff1a;两房 关键词&#xff1a;多条件查询 AND BETWEEN LIKE 组合运用&#x1f3ac; 开场白“听起来不难&a…

深入解析YARN中的FairScheduler与CapacityScheduler:资源分配策略的核心区别

YARN资源调度器概述在Hadoop生态系统中&#xff0c;YARN&#xff08;Yet Another Resource Negotiator&#xff09;作为核心资源管理平台&#xff0c;其架构设计将计算资源管理与作业调度解耦&#xff0c;形成了"全局资源管理器&#xff08;ResourceManager&#xff09;节…

基于Seata的微服务分布式事务实战经验分享

基于Seata的微服务分布式事务实战经验分享 1. 业务场景描述 在电商系统中&#xff0c;用户下单会涉及多个微服务&#xff1a;订单服务&#xff08;Order Service&#xff09;、库存服务&#xff08;Inventory Service&#xff09;、账户服务&#xff08;Account Service&#x…

Linux库——库的制作和原理(2)_库的原理

文章目录库的原理理解目标文件ELF文件读取ELF的工具——readelfELF从形成到加载的轮廓ELF形成可执行文件ELF可执行的加载理解链接与加载静态链接ELF加载和进程地址空间虚拟地址 & 逻辑地址重新理解进程地址空间动态链接和动态库的加载进程如何找到动态库多个进程之间如何共…

Redis C++客户端——通用命令

目录 代码案例 get和set部分 exists部分 del部分 keys部分 expire部分 type部分 本篇文章主要是通过redis-plus-plus库使用通用命令。 代码案例 下面用一个代码演示&#xff1a; #include <sw/redis/redis.h> #include <iostream> #include <vecto…

手机开启16k Page Size

我买了一个pixel8的手机&#xff0c;系统是Android16,如下操作都是基于这个手机做的。 https://source.android.com/docs/core/architecture/16kb-page-size/16kb-developer-option?hlzh-cn#use_16kb_toggle 使用 16 KB 切换开关 按照开发者选项文档中的指示启用开发者选项。…

VLAN的划分(基于华为eNSP)

VLAN的划分 前言&#xff1a;为什么VLAN是现代网络的“隐形骨架”&#xff1f; 当一台办公室电脑发送文件给隔壁工位的同事时&#xff0c;数据如何精准抵达目标而不“打扰”其他设备&#xff1f;当企业财务部的敏感数据在网络中传输时&#xff0c;如何避免被其他部门的设备“窥…