首页 游戏 软件 资讯 排行榜 专题
首页
业界动态
字节、腾讯前端都在用的 Axios 封装方案!Vue/React/小程序一套通吃,复制即用

字节、腾讯前端都在用的 Axios 封装方案!Vue/React/小程序一套通吃,复制即用

热心网友
15
转载
2026-04-30

这套 2026 年最新 Axios 通用封装,一行配置搞定全局拦截、自动鉴权、错误统一处理、防重复请求——Vue2/Vue3、React、Uniapp、微信小程序、Node.js 全端兼容,线上项目稳定运行超 18 个月!

还在为每个接口手动添加 token 而烦恼?还在重复编写 401 状态码的跳转逻辑?试试这套 2026 年最新打磨的 Axios 通用封装方案。只需一行配置,就能一站式解决全局拦截、自动鉴权、统一错误处理和防重复请求等核心问题。它完美兼容 Vue2/Vue3、React、Uniapp、微信小程序乃至 Node.js 等主流技术栈,并且已经在线上真实项目中稳定运行超过 18 个月。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

如果你也受够了以下这些开发“日常”:

  • 每个新项目都要从头重写一遍请求逻辑。
  • 登录过期后页面白屏,用户体验糟糕却无人处理。
  • 用户频繁点击按钮,导致接口被重复刷爆。
  • 小程序和 H5 项目的请求逻辑不一致,维护成本直接翻倍。

那么,这篇经过字节跳动、腾讯等大厂内部项目验证的封装方案,正是为你准备的。无需重复造轮子,直接复制粘贴,今天就能让项目的接口层变得稳如泰山。

一、先说痛点:裸写 Axios 的 5 大“致命伤”

一个真实的案例足以说明问题:某电商项目由于未做防重复请求处理,在大促活动期间,因用户重复点击导致大量重复下单,最终造成的直接经济损失超过 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.signal
    pending.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) => {
    // 清除 pending
    removePending(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 || '请求失败') // Web
    return 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' // Web
      uni.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 / 小程序双端兼容:智能判断环境,分别使用 localStorageuni.getStorageSync 处理 token。
  • 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 uploadA vatar = (file) => {
  const formData = new FormData()
  formData.append('a vatar', file)
  return request.post('/upload/a vatar', formData, {
    headers: { 'Content-Type': 'multipart/form-data' }
  })
}

2. 页面中使用(Vue/React 完全一致)

import { getUserInfo } from '@/api/user'

async function loadProfile() {
  try {
    const userInfo = await getUserInfo() // 直接拿到 data
    setUser(userInfo)
  } catch (err) {
    // 全局已处理错误,此处可做特殊逻辑(如埋点)
    console.log('获取用户信息失败', err)
  }
}

最大的优势在于:业务代码只需关注“成功后的数据”,所有常规错误都已在拦截器中统一兜底处理。

四、多端适配指南(一套代码跑全端)

一个实用技巧:通过 typeof window !== 'undefined' 来判断当前是否为 Web 环境,从而实现一套代码在不同端的兼容性适配。

五、避坑指南:3 个高频雷区

1. 坑一:baseURL 写死,环境切换崩溃

正确做法是使用环境变量进行动态配置:

# .env.development
VITE_API_BASE_URL = 'https://dev.api.com'

# .env.production
VITE_API_BASE_URL = 'https://prod.api.com'

2. 坑二:401 不清 token,导致无限跳转

必须在 401 错误的处理逻辑中,同步清除本地存储的 token。否则,即使用户被重定向到登录页,浏览器或小程序中仍可能携带旧的 token,导致无限循环跳转。

3. 坑三:防重逻辑没覆盖 POST 参数

很多简易的防重方案只比对 URL 和查询参数(params),而忽略了 POST 请求的请求体(data)。必须将请求体数据也参与防重 key 的生成,否则表单提交等 POST 操作依然会产生重复请求。

六、进阶扩展(按需添加)

这套基础骨架之上,还可以根据项目需求进行灵活扩展:

  • 自动刷新 token:在 401 时尝试使用 refresh_token 换取新的 access_token,并自动重发原请求。
  • 请求日志:记录接口耗时、请求参数等信息,便于性能分析和问题排查。
  • Mock 支持:在开发环境无缝接入 Mock 数据,不影响前后端联调。
  • 签名加密:对于金融、支付等安全要求高的项目,可在请求前自动完成参数签名和加密。

这套方案并非“玩具代码”,它已经在多个用户量达百万级别的生产项目中得到了充分验证。当你不再需要为接口层的各种琐碎错误而焦头烂额时,就会明白——这波封装,绝对值了。

来源:https://www.51cto.com/article/842141.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

Sublime支持的React开发插件有哪些_Sublime配置JSX语法高亮
编程语言
Sublime支持的React开发插件有哪些_Sublime配置JSX语法高亮

Sublime Text 4 配置 JSX 语法高亮:当前唯一稳定的方案解析 如果你正在 Sublime Text 4 里写 React,可能会发现一个尴尬的事实:编辑器本身对 JSX 语法“视而不见”。没错,Sublime Text 并不原生支持 JSX,必须依赖插件来接管语法解析。那么问题来了,

热心网友
04.29
React Router 6.15 中实现页面跳转时自动滚动到顶部的完整方案
前端开发
React Router 6.15 中实现页面跳转时自动滚动到顶部的完整方案

在 React Router 6 15 中,ScrollRestoration 组件可原生支持导航时滚动至顶部及历史回退时恢复滚动位置;若需更精细控制,也可通过自定义 useScrollToTop Hook 或布局级组件实现。 在 React Router 6 15 中,`ScrollRestora

热心网友
04.28
如何在 React Native 中为映射数组中的单个被点击项动态切换文本颜色
前端开发
如何在 React Native 中为映射数组中的单个被点击项动态切换文本颜色

如何在 React Native 中为映射数组中的单个被点击项动态切换文本颜色 本文探讨在 React Native 中管理多个独立项交互状态的正确方法,目标是实现用户点击某一个音名时(例如使其变绿),仅该元素被高亮,而不是所有元素统一响应。解决问题的关键在于采用对象或数组记录每个索引的独立选中状态

热心网友
04.27
如何正确在 React 中同步本地存储与商品详情页的购物车数据
前端开发
如何正确在 React 中同步本地存储与商品详情页的购物车数据

如何正确在 React 中同步本地存储与商品详情页的购物车数据 本文解决因误将本地存储的购物车数组赋值给商品状态(product)导致的 undefined 报错问题,详解 useState 初始化逻辑错误、useEffect 缓存时机缺陷,并提供安全的本地存储读写实践与 Redux 同步方案。 在

热心网友
04.26
如何让 React 侧边栏(Sidebar)过渡动画更平滑?
前端开发
如何让 React 侧边栏(Sidebar)过渡动画更平滑?

本文深入解析 React 侧边栏动画卡顿、闪现的常见问题,提供一套完整的解决方案。通过摒弃 display 属性,巧妙结合 CSS transition、visibility、opacity 与 zIndex,实现流畅自然的 2 5 秒展开收起动画,提升用户体验与页面专业度。 你是否在开发 Reac

热心网友
04.25

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

滚筒洗衣机如何拆洗内桶最彻底?
电脑教程
滚筒洗衣机如何拆洗内桶最彻底?

滚筒洗衣机内桶最彻底的清洁方式 想给滚筒洗衣机内桶来一次真正彻底的清洁?答案只有一个:规范拆解,进行物理级的深度清洗。这可不是简单扔两包清洁剂就能搞定的事,它需要一套严格的技术流程——从断电断水开始,到分步拆卸、精准复装,每一步都马虎不得。核心步骤是:先拆外壳和前封板,再处理门锁和外筒固定结构,接着

热心网友
04.30
opporenocolor11系统可以升级ColorOS几
电脑教程
opporenocolor11系统可以升级ColorOS几

OPPO Reno11系列ColorOS 15 0正式版升级指南与体验解析 好消息来了!OPPO Reno11系列,包括Reno11 5G和Reno11 Pro 5G,现在已经可以升级到ColorOS 15 0正式版了。官方已经为符合条件的用户开放了“新版本尝鲜”通道。不过,升级前有个硬性门槛:你的

热心网友
04.30
老年助听器怎么安装?
电脑教程
老年助听器怎么安装?

老年助听器的安装:一套始于专业、终于适应的科学闭环 很多人以为,给老人戴上助听器,就像戴上一副老花镜那么简单。其实不然。一套真正有效的助听方案,远不止“开机出声”这么简单,它是一套环环相扣的科学流程:从专业的听力验配开始,到个体化的设备适配,再到循序渐进的听觉适应,三者缺一不可。这个过程,始于持证听

热心网友
04.30
以太坊7月收益减半怎么算
web3.0
以太坊7月收益减半怎么算

以太坊7月收益减半怎么算 先说一个核心结论:即将到来的以太坊收益减半,其核心逻辑在于验证者从每个区块中获得的基础共识奖励,将被直接砍掉一半。当然,这并非简单的“腰斩”,因为最终落到个人口袋里的年化收益率,是基础奖励、全网质押总量、Gas费以及MEV(最大可提取价值)收益共同作用的结果。综合来看,个人

热心网友
04.30
CentOS Python数据分析怎么实现
编程语言
CentOS Python数据分析怎么实现

在CentOS系统上实现Python数据分析 想在CentOS服务器上搭建一套高效、稳定的Python数据分析环境?对于许多开发者和数据团队而言,在Linux生产环境中部署数据分析平台是常见需求。本文将提供一份经过验证的、从零开始的详细配置指南,帮助您在CentOS系统上快速构建专业的Python数

热心网友
04.30