前后端交互的桥梁:Axios
前后端交互的桥梁:Axios
在 Web 开发中,我们通常采用前后端分离的模式:前端(如 Vue)通过 MVVM 模式负责页面的渲染与交互,后端(如 FastAPI)负责业务逻辑与数据处理。在这两者之间,需要一座桥梁来传递数据,这座桥梁就是 HTTP 请求。前端如何向后端发起请求?在浏览器环境下,我们通常称之为 AJAX(Asynchronous JavaScript and XML)技术。而在 Vue 生态中,实现这一功能的“事实标准”库,便是 Axios。
Axios 是一个基于 Promise 的网络请求库,它既可以在浏览器中运行,也可以在 Node.js 环境中使用。相比原生 fetch,Axios 提供了更多强大的功能。最简单的使用方式如下:
1 | import axios from 'axios'; |
在实际的项目中,我们的后端接口成百上千,且部署环境(开发、测试、生产)各不相同。如果像上面那样每次都硬编码 URL,代码将变得难以维护。因此,标准做法是封装一个统一的 Axios 实例。我们通常会创建一个单独的文件(例如 src/api/index.ts),在其中配置基础 URL、超时时间以及拦截器。
1 | import axios, { type AxiosInstance, type AxiosError, type InternalAxiosRequestConfig } from 'axios' |
请求拦截器在 apiClient 发送任何请求之前,它会先检查浏览器的 localStorage 中是否有 access_token。如果找到了,就会自动在 HTTP Header 中加上 Authorization: Bearer <token>。这样我们在具体的业务组件中(比如获取用户列表)只需要关注业务逻辑,完全不需要操心认证的问题,因为拦截器已经默默帮我们做好了。
响应拦截器在后端返回数据前,它会先过一遍。如果后端返回了 401 Unauthorized,说明用户的登录令牌过期了。此时我们需要做两件事:
- 清除本地无效的 Token:
localStorage.removeItem(...) - 跳转回登录页:这里我们直接导入了 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 执行之前。一旦创建,这个实例会一直驻留在浏览器的内存堆中。直到用户关闭标签页或刷新浏览器(刷新本质上是销毁当前页面应用并重新加载),这个实例才会被销毁。