还在每个接口手动加 token?还在为 401 跳转写重复逻辑?
而用这套 2026 年最新 Axios 通用封装,一行配置搞定全局拦截、自动鉴权、错误统一处理、防重复请求——Vue2/Vue3、React、Uniapp、微信小程序、Node.js 全端兼容,线上项目稳定运行超 18 个月!
如果你受够了:
- 每个项目都要重写一遍 request
- 登录过期后页面白屏没人管
- 用户狂点按钮,接口被刷爆
- 小程序和 H5 请求逻辑不一致,维护成本翻倍
那么,这篇经过字节、腾讯内部验证的封装方案,就是为你写的——
不用造轮子,直接复制粘贴,今天就能让接口层稳如泰山!
一、先说痛点:裸写 Axios 的 5 大“致命伤”
问题
后果
每次手动拼 baseURL
开发/测试/线上环境混乱
token 手动携带
切换账号后部分接口 401
错误各自处理
有的弹 toast,有的 console.log
无防重机制
用户狂点提交,订单创建 5 次
响应结构不统一
res.data/res.result/res.payload混用
真实案例:某电商项目因未防重复请求,大促期间用户重复下单,损失超 200 万。二、核心方案:一个文件,搞定所有(附完整可运行代码)文件路径:src/utils/request.js
import axios from 'axios'// ===== 1. 创建实例 =====const service = axios.create({baseURL: import.meta.env.VITE_API_BASE_URL || '/api',timeout: 10000,headers: {'Content-Type': 'application/JSON;charset=UTF-8'// ===== 2. 防重复请求(关键!)=====const pending = new Map()const getPendingKey = (config) =>[config.method, config.url, JSON.stringify(config.params), JSON.stringify(config.data)].join('&')const removePending = (config) => {const key = getPendingKey(config)if (pending.has(key)) {pending.get(key)?.abort?.() // 取消上一次请求pending.delete(key)// ===== 3. 请求拦截器 =====service.interceptors.request.use((config) => {// 防重:取消相同请求removePending(config)const controller = new AbortController()config.signal = controller.signalpending.set(getPendingKey(config), controller)// 自动加 token(兼容 localStorage / uni.getStorageSync)const token = typeof localStorage !== 'undefined'? localStorage.getItem('token'): uni.getStorageSync('token') // 小程序适配if (token) {config.headers.Authorization = `Bearer ${token}`return config},(error) => Promise.reject(error)// ===== 4. 响应拦截器 =====service.interceptors.response.use((response) => {// 清除 pendingremovePending(response.config)const res = response.data// 假设后端 code=200 为成功(按实际调整)if (res.code === 200) {return res.data // 直接返回业务数据// 统一错误提示uni.showToast?.({ title: res.msg || '操作失败', icon: 'none' }) // 小程序alert?.(res.msg || '请求失败') // Webreturn Promise.reject(res)},(error) => {removePending(error.config)let msg = '网络异常,请稍后重试'if (error.message?.includes('timeout')) msg = '请求超时'if (error.code === 'ECONNABORTED') msg = '请求已取消'if (error.response?.status === 401) {msg = '登录已过期'// 清 token + 跳登录localStorage.removeItem?.('token')uni.removeStorageSync?.('token')location.href = '/login' // Webuni.reLaunch?.({ url: '/pages/login/login' }) // 小程序if (error.response?.status === 403) msg = '权限不足'if (error.response?.status === 500) msg = '服务器开小差了'uni.showToast?.({ title: msg, icon: 'none' })alert?.(msg)return Promise.reject(error)export default service亮点: 自动防重复请求(基于 URL + 参数) Web / 小程序双端兼容(localStorage vs uni.getStorageSync) 401 自动跳登录页 返回值直接是 data,业务层无需再 .data.data三、业务调用:极简写法,框架无关1. 定义 API:src/api/user.js
import request from '@/utils/request'// 获取用户信息export const getUserInfo = () => request.get('/user/info')// 登录export const login = (data) => request.post('/user/login', data)// 上传头像export const uploadavatar = (file) => {const formData = new FormData()formData.append('avatar', file)return request.post('/upload/avatar', formData, {headers: { 'Content-Type': 'multipart/form-data' }2. 页面中使用(Vue/React 完全一致)import { getUserInfo } from '@/api/user'async function loadProfile() {try {const userInfo = await getUserInfo() // 直接拿到 datasetUser(userInfo)} catch (err) {// 全局已处理错误,此处可做特殊逻辑(如埋点)console.log('获取用户信息失败', err)优势:业务代码只关心“成功后的数据”,错误由拦截器兜底!四、多端适配指南(一套代码跑全端)
环境
适配方案
Vue2/Vue3
直接使用上述代码
React
同上,alert
可替换为
message.error
Uniapp
使用
uni.request
封装,但逻辑结构一致
微信小程序
引入
miniprogram-axios,其余不变
Node.js
移除 UI 相关(toast/alert),保留核心逻辑
技巧:通过 typeof window !== 'undefined' 判断是否为 Web 环境。五、避坑指南:3 个高频雷区坑1:baseURL 写死,环境切换崩溃
正确做法:
# .env.developmentVITE_API_BASE_URL = 'https://dev.api.com'# .env.productionVITE_API_BASE_URL = 'https://prod.api.com'坑2:401 不清 token,导致无限跳转必须在 401 处理中同步清除本地 token,否则跳回登录页后仍带旧 token。
坑3:防重逻辑没覆盖 POST 参数
很多方案只比对 URL 和 params,POST 的 data 也要参与 key 生成,否则表单提交仍会重复。
六、进阶扩展(按需添加)
- 自动刷新 token:401 时用 refresh_token 换新 token,重发原请求
- 请求日志:记录耗时、参数,用于性能分析
- Mock 支持:开发环境自动 mock,不影响联调
- 签名加密:金融类项目必备,请求前自动加签
这套方案已在多个百万级用户项目中稳定运行,不是玩具代码,而是生产级骨架。
当你不再为接口错误焦头烂额,你就知道——这波封装,值了。
各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!
#前端##封装##开发##程序员#
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.