惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX - 技术
D
DataBreaches.Net
阮一峰的网络日志
阮一峰的网络日志
Recent Announcements
Recent Announcements
V
V2EX
Hugging Face - Blog
Hugging Face - Blog
T
The Exploit Database - CXSecurity.com
Simon Willison's Weblog
Simon Willison's Weblog
Cisco Talos Blog
Cisco Talos Blog
Microsoft Security Blog
Microsoft Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
K
Kaspersky official blog
F
Fortinet All Blogs
GbyAI
GbyAI
Forbes - Security
Forbes - Security
The Cloudflare Blog
博客园 - 司徒正美
博客园_首页
量子位
Schneier on Security
Schneier on Security
G
GRAHAM CLULEY
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Proofpoint News Feed
N
News | PayPal Newsroom
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
T
Tor Project blog
V
Vulnerabilities – Threatpost
Y
Y Combinator Blog
Jina AI
Jina AI
Help Net Security
Help Net Security
T
Threat Research - Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cybersecurity and Infrastructure Security Agency CISA
Project Zero
Project Zero
N
News and Events Feed by Topic
I
Intezer
B
Blog
美团技术团队
C
CERT Recently Published Vulnerability Notes
NISL@THU
NISL@THU
L
LINUX DO - 最新话题
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Blog — PlanetScale
Blog — PlanetScale
AWS News Blog
AWS News Blog
T
Tailwind CSS Blog
The Last Watchdog
The Last Watchdog
雷峰网
雷峰网
有赞技术团队
有赞技术团队

windsong

从画图纸到捏泥巴:从后端到 JavaScript 清华校园网认证笔记 摆脱“被动焦虑”的终极解药:一个尼采主义者的自我救赎与“强力意志”觉醒 windsong Vue 组件通信 词法作用域与动态作用域 全栈架构:三套 Schema Pinia Store :前端的 MVVM 解耦 全栈容器化应用的环境变量管理 早抛晚捕:异常处理 股票市场常识 大噜村的债务:过去和未来 大噜村的发展故事 重读设计模式:从理论到实践的反思(二) Transformer 个人入门 Go Viper:设计哲学与最佳实践 简单的 Go WebSocket 服务器 最简单的 Go HTTP 服务器 Go 语言核心机制:命名类型与接口
前后端交互的桥梁:Axios
xxxx · 2026-01-10 · via windsong

前后端交互的桥梁:Axios

在 Web 开发中,我们通常采用前后端分离的模式:前端(如 Vue)通过 MVVM 模式负责页面的渲染与交互,后端(如 FastAPI)负责业务逻辑与数据处理。在这两者之间,需要一座桥梁来传递数据,这座桥梁就是 HTTP 请求。前端如何向后端发起请求?在浏览器环境下,我们通常称之为 AJAX(Asynchronous JavaScript and XML)技术。而在 Vue 生态中,实现这一功能的“事实标准”库,便是 Axios

Axios 是一个基于 Promise 的网络请求库,它既可以在浏览器中运行,也可以在 Node.js 环境中使用。相比原生 fetch,Axios 提供了更多强大的功能。最简单的使用方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
import axios from 'axios';


axios.get('http://127.0.0.1:8000/items')
.then(response => {

console.log(response.data);
})
.catch(error => {

console.error(error);
});

在实际的项目中,我们的后端接口成百上千,且部署环境(开发、测试、生产)各不相同。如果像上面那样每次都硬编码 URL,代码将变得难以维护。因此,标准做法是封装一个统一的 Axios 实例。我们通常会创建一个单独的文件(例如 src/api/index.ts),在其中配置基础 URL、超时时间以及拦截器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import axios, { type AxiosInstance, type AxiosError, type InternalAxiosRequestConfig } from 'axios'
import router from '@/router'


export interface ApiError {
detail: string
status: number
}


const apiClient: AxiosInstance = axios.create({

baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8000/api/v1',
timeout: 10000,
headers: {
'Content-Type': 'application/json'
}
})


apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {

const token = localStorage.getItem('access_token')
if (token && config.headers) {

config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => Promise.reject(error)
)


apiClient.interceptors.response.use(
(response) => response,
(error: AxiosError<ApiError>) => {

if (error.response?.status === 401) {

localStorage.removeItem('access_token')



router.push({
path: '/login',
query: { redirect: router.currentRoute.value.fullPath }
})
}
return Promise.reject(error)
}
)

export default apiClient

请求拦截器在 apiClient 发送任何请求之前,它会先检查浏览器的 localStorage 中是否有 access_token。如果找到了,就会自动在 HTTP Header 中加上 Authorization: Bearer <token>。这样我们在具体的业务组件中(比如获取用户列表)只需要关注业务逻辑,完全不需要操心认证的问题,因为拦截器已经默默帮我们做好了。

响应拦截器在后端返回数据前,它会先过一遍。如果后端返回了 401 Unauthorized,说明用户的登录令牌过期了。此时我们需要做两件事:

  1. 清除本地无效的 Token:localStorage.removeItem(...)
  2. 跳转回登录页:这里我们直接导入了 Vue Router 的实例 router,并调用 router.push('/login')。这实现了前端的自动化闭环——用户无需刷新页面,一旦 Token 失效,系统会自动将其踢回登录页。

在上述代码中,我们直接 export default apiClient,然后在其他组件中 import apiClient 直接使用。

在后端服务层开发中,我们习惯定义一个 UserService 类,然后通过依赖注入将其实例化并注入到 Controller 或 Logic 层中。而在现代前端中,模块即单例。当 import apiClient 时,无论你在项目中引用了多少次,引用的都是同一个 apiClient 对象实例。这实际上是一种隐式的单例模式。对于无状态的 HTTP 客户端来说,这非常高效且合理,我们不需要像后端那样复杂的 DI 容器来管理生命周期。

当 Vue 应用启动,浏览器加载 main.ts 并解析依赖树时。一旦执行到 import ... from './api' 这一行,对应的 .ts 文件就会被立即执行,apiClient 实例随之创建。这通常发生在 App.vue 挂载甚至 createApp 执行之前。一旦创建,这个实例会一直驻留在浏览器的内存堆中。直到用户关闭标签页或刷新浏览器(刷新本质上是销毁当前页面应用并重新加载),这个实例才会被销毁。