这篇文章的主题主要是两件事
1.对axios这个技术栈做一个沉淀
2.对于vue-cli这个技术栈需要对axios做的配置
1.对axios这个技术栈做一个沉淀
1.什么是axios,用通俗的语言,解释一下他主要解决什么问题
2.对于axios在引入到工程的时候需要做什么配置
3.axios的知识体系是什么,提供了哪些机制供使用
4.axios实现的底层原理
这篇文章我们来系统地梳理一下 Axios 这个技术栈,并探讨在 Vue CLI 项目中如何高效地配置它。
1. 对 Axios 技术栈做一个沉淀
1.1 通俗理解:Axios 是什么,解决了什么问题?
一句话概括:Axios 是一个基于 Promise 的、用于浏览器和 Node.js 环境的 HTTP 客户端。
通俗地讲,如果你写了一个前端页面,想让这个页面在不刷新、不跳转的情况下,从后端服务器上拿到数据并显示出来(比如加载更多评论、登录验证),你就需要发送网络请求。
以前,我们可能直接用浏览器自带的 XMLHttpRequest(XHR)或 fetch。但它们用起来不够方便,要么代码写起来很繁琐,要么功能不够完善。
Axios 的核心价值在于:
- 统一、简洁的 API:它封装了各种复杂的请求方式(GET, POST, PUT, DELETE 等),让你用一行简洁的代码就能发起请求 。
- 自动化数据转换:它会自动将请求数据转换成 JSON 格式,并自动解析返回的 JSON 数据,省去了手动转换的麻烦 。
- 强大的拦截器:你可以在请求发送前或响应到达前"拦截"它们,统一添加 token、处理 loading 状态、处理错误日志等 。
- 高兼容性与环境自适应 :它在浏览器端使用 XHR,在 Node.js 端使用原生
http模块,一套代码两端通用。它也能自动防御 XSRF/CSRF 攻击 。
1.2 工程引入:在工程中需要做什么配置?
如果直接将 Axios 引入工程而不加任何封装,代码会显得非常冗余(每次都要写 baseURL、超时时间、错误处理等)。因此,更专业的做法是在项目中对其进行二次封装。
通常需要做以下几项核心配置:
- 创建实例 (
axios.create) :不要直接使用全局的axios,而是创建一个新的实例。这样可以为不同的接口配置不同的基础路径(例如:有的请求/api/user,有的请求/api/order),且互不影响 。 - 基础路径 (
baseURL) :设置接口请求的公共地址(如https://api.example.com)。这能极大简化代码,维护时改一个地方即可 。 - 超时时间 (
timeout):设置请求响应的最大等待时间(如 10000 毫秒),避免请求长时间挂起 。 - 拦截器配置 :
- 请求拦截器:在发送请求前,给 header 添加 Token 等鉴权信息。
- 响应拦截器:对返回的数据进行统一处理,例如解构数据层,或统一处理 401/403 等权限错误 。
1.3 知识体系:Axios 提供了哪些机制?
Axios 的知识体系可以概括为一个中心、两个基本点、三大扩展机制:
一个中心:核心 API(Axios)
这是入口,提供了两种调用方式。一种是直接传配置 axios(config),另一种是别名方法 axios.get(url, config)。它的灵活性在于,既可以像函数一样调用,又可以像对象一样使用 .get 和 .post 方法 。
两个基本点:实例与配置
- 实例 (
create):允许你创建多个拥有不同默认配置的 Axios 对象 。 - 配置 (
Config):这是 Axios 的灵魂,支持全局配置、实例配置和请求级配置的深度合并,粒度极细 。
三大扩展机制
- 拦截器 (
Interceptor) :- 这是 Axios 最强大的设计模式(类似于中间件)。它允许你在
then或catch之前,链式地处理请求或响应。 - 执行顺序 :请求拦截器是后添加的先执行 (像栈);响应拦截器是先添加的先执行(像队列)。
- 这是 Axios 最强大的设计模式(类似于中间件)。它允许你在
- 适配器 (
Adapter) :- 这是 Axios 实现环境自适应 的关键。它会根据当前环境(浏览器还是 Node.js)自动选择适配器(XHR 或
http)。理论上,你甚至可以自定义适配器来模拟请求或使用 WebSocket 。
- 这是 Axios 实现环境自适应 的关键。它会根据当前环境(浏览器还是 Node.js)自动选择适配器(XHR 或
- 取消请求 (
CancelToken/AbortSignal) :- 提供了主动取消正在进行的 HTTP 请求的能力。这在切换页面或频繁点击搜索时非常有用,可以避免旧数据覆盖新数据或浪费带宽 。
1.4 底层原理:Axios 是如何实现的?
Axios 的源码并不复杂,其核心设计哲学是链式调用 与适配器模式。
-
执行流程是 Promise 链 :
当你调用
axios()时,它并不是直接发送请求。而是像一个管道一样,把"请求拦截器"、"请求发送核心"、"响应拦截器"组装成一个数组[请求拦截器成功, 请求拦截器失败, 发送请求, 空, 响应拦截器成功, 响应拦截器失败]。然后,它通过一个
Promise链,依次把这个数组中的任务执行下去 。 -
核心引擎 (
dispatchRequest) :这是请求的真正处理中心。在这里,它会做三件事:
- 转换数据 :调用
transformRequest对数据进行格式化。 - 适配器调度 :根据环境调用
xhrAdapter(浏览器)或httpAdapter(Node.js)。 - 底层实现 :在浏览器端,本质还是创建了一个
XMLHttpRequest对象,只不过 Axios 用 Promise 将其包裹并完善了事件处理 。
- 转换数据 :调用
-
拦截器的实现 :
InterceptorManager类维护了一个数组。当你调用use时,就是把函数推入数组。在请求环节,Axios 会将数组里的函数按顺序/倒序取出,穿插在上述的 Promise 链中执行 。
2. Vue CLI 中需要为 Axios 做的配置(重点:跨域)
在 Vue CLI 项目中,除了上述的代码逻辑封装,最关键的工程配置就是处理跨域问题。
由于 Vue CLI 开发服务器(通常运行在 localhost:8080)和后端服务器(如 localhost:5000)端口不同,浏览器会限制发送请求。
Vue CLI 提供了一个开箱即用的代理服务器 解决方案。你不需要去修改 Nginx 或后端代码,只需要修改 vue.config.js 文件 。
方式一:简单代理(适用于单一后端)
如果你只有一个后端服务器,可以使用最简单的配置。
javascript
// vue.config.js
module.exports = {
devServer: {
proxy: 'http://localhost:5000' // 所有未知请求都会转发给这个地址
}
}
- 原理 :当你请求
8080/students但本地没有这个资源时,代理服务器会把这个请求转发给5000/students。 - 缺点:不支持配置多个代理,且无法精确控制哪些请求走代理。
方式二:进阶代理(推荐,适用于多后端或精确控制)
这是更专业、更常用的配置方式,通过路径前缀来触发代理。
javascript
// vue.config.js
module.exports = {
devServer: {
proxy: {
// 凡是以 '/api' 开头的请求,都会走这个代理
'/api': {
target: 'http://localhost:5000', // 目标服务器地址
ws: true, // 支持 websocket
changeOrigin: true, // 修改请求头中的 host 为目标地址(重要,解决后端校验问题)
pathRewrite: {
'^/api': '' // 将请求路径中的 '/api' 去掉
}
},
// 还可以配置多个,比如专门代理图片或其他服务
'/foo': {
target: 'http://localhost:5001',
pathRewrite: { '^/foo': '' }
}
}
}
}
- 关键配置解析 :
'^/api':请求路径中只要包含/api,就会被拦截。changeOrigin: true:建议必须开启 。它可以控制代理服务器请求目标时的Host头。设为true可以"欺骗"后端服务器,让它以为请求来自同源,避免后端服务器的接口防火墙拦截 。pathRewrite:由于我们给请求路径加了前缀/api(为了防止和本地静态资源冲突),但后端接口可能没有这个前缀,所以需要重写去掉 。
总结 :在 Vue CLI 项目中,封装 Axios 实例 + 配置 vue.config.js 代理 是一套标准的组合拳。封装负责代码整洁和功能增强,代理负责解决开发环境最头痛的跨域通讯问题。