目录
[1 Axios简介](#1 Axios简介)
[2 Axios安装](#2 Axios安装)
[3 Axios简单使用](#3 Axios简单使用)
[4 Axios进阶使用](#4 Axios进阶使用)
[4.1 全局统一配置](#4.1 全局统一配置)
[4.2 导出axios实例](#4.2 导出axios实例)
[4.3 拦截器](#4.3 拦截器)
[4.3.1 请求拦截器](#4.3.1 请求拦截器)
[4.3.2 响应拦截器](#4.3.2 响应拦截器)
[5 Axios项目使用](#5 Axios项目使用)
[5.1 跨域问题](#5.1 跨域问题)
[5.1.1 同源策略与跨域问题](#5.1.1 同源策略与跨域问题)
[5.1.2 跨域问题解决方案](#5.1.2 跨域问题解决方案)
[5.2 代理服务器](#5.2 代理服务器)
[5.2.1 三种常见场景的跨域问题](#5.2.1 三种常见场景的跨域问题)
[5.2.2 代理服务器配置](#5.2.2 代理服务器配置)
[5.3 封装使用流程](#5.3 封装使用流程)
[5.3.1 axios实例封装](#5.3.1 axios实例封装)
[5.3.2 代理服务器封装](#5.3.2 代理服务器封装)
[5.3.3 请求接口方法封装](#5.3.3 请求接口方法封装)
1 Axios简介
Axios是一个基于promise( Promise是JavaScript的异步编程的对象,用来接收异步操作成功或失败以及数据的对象)的网络请求库,可用于node.js和浏览器中。用于node.js就是后端开发发送http请求,用于浏览器就是前端开发发送ajax请求。
Aaxios(ajax i/o system)本质上也是对原生XHR(XMLHttpReques)的封装,只不过它是基于promise的,是promise的实现版本,符合最新的ES规范。
Axios作为请求库,具有如下优势:
- 标准化:统一浏览器/Node环境请求接口。
- 拦截器机制:可拦截请求/响应,实现全局逻辑(如Token注入、错误处理)。
- 自动转换:请求/响应数据自动转为JSON,支持自定义转换逻辑。
- 取消请求:通过CancelToken中止长时间未响应的请求。
2 Axios安装
终端打开项目地址,输入如下命令:
bash
npm install axios # Node 环境

3 Axios简单使用
要使用Axios,首先需要引入axios包,然后通过create()创建axios实例,才能使用:
javascript
import axios from 'axios'
javascript
// GET 请求(参数自动拼接到 URL)
axios.get('/user', { params: { id: 123 } })
.then(res => console.log(res.data))
.catch(err => console.error(err));
// POST 请求(自动序列化 JSON)
axios.post('/login', { username: 'admin', pwd: '123' })
.then(res => console.log(res));
上述通过引入axios,使用get发送GET请求,使用post发送POST请求,通过Promise对象的.then和.catch等链式调用的方式来获取成功态的Promise实例和拒绝态的Promise实例(失败)。
除了get和post请求,还有其它请求方式:
- get:获取数据
- post:提交数据(表单提交与文件上传)
- patch:更新数据(只将修改的数据推送到后端(服务端))
- put:更新数据(所有数据推送到服务端)
- delete:删除数据
4 Axios进阶使用
上述使用方式特点是功能简单,并且只能在单个组件中使用,如果要全局使用,就可以创建Axios实例并导出,灵活配置后端URL:
4.1 全局统一配置
全局统一配置Axios实例一般需要单独创建js文件,在其中创建Axios实例并导出:
javascript
// 创建 axios 实例
const instance = axios.create({
//后端服务器ip地址
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 600000
})
baseURL参数是后端服务器的ip地址,timeout是超时时间。
建议:后端服务器ip地址不要写死,根据环境变量或常量进行灵活动态变化。
4.2 导出axios实例
通过export导出默认的axios实例,接收5个参数:
javascript
// 导出自定义请求函数(url是接口地址(因为基本ip地址已经封装,只需接口地址再拼接即可)、请求类型、数据、参数、请求头)
export default ({ url, method, data, params, header }) => {
return instance({
url,
method,
data,
params,
header
})
}
要使用axios实例的组件需要导入该实例,并传入url(接口地址)、method(请求方法)、data(发送的数据)、params(请求参数)、header(请求头),即可发送请求。
接口地址会被自动拼接到后端服务器ip后从而发送完整的请求路径。
4.3 拦截器
可以在创建axios实例后,对实例添加拦截器,然后在请求发送前和响应接收前做一些特殊处理(公共处理:每个接口都需要进行步骤,比如用户鉴权Token)。
4.3.1 请求拦截器
请求拦截器在请求发送前进行拦截请求,并处理一些事情,比如请求头添加Token:
javascript
// 添加请求拦截器
instance.interceptors.request.use(
(config) => {
// config就是和此次请求相关的信息,包含请求地址,方法,参数,头等
const userStore = useUserStore()
const { token } = userStore
// 如果有Token,说明已经登录过,所有的登录后请求头应该添加Token
if (token) {
config.headers.Authorization = token
}
// 必须返回config,否则无法获取响应数据
return config
},
(error) => {
// 对请求错误做些什么
return Promise.reject(error)
}
)
4.3.2 响应拦截器
响应拦截器是在响应被处理前进行拦截,可以对响应数据进行状态码验证、数据解构等操作:
javascript
// 添加响应拦截器
instance.interceptors.response.use(
(response) => {
// 解构:从响应response对象的data属性才能拿到后端返回的数据
const { code, data, msg } = response.data
if (code !== 200000) {
// 返回一个失败态的 Promise 实例
// 拦截器后的接口请求方就会收到错误的Promise实例,即被.catch到
return Promise.reject(new Error(msg))
}
// 否则返回纯粹的 data 数据
return data
},
(error) => {
// 所有的接口响应失败都必须先执行这里
const { response, status } = error
//比如http状态是401
if (status === 401) {
// token 过期
// TODO相应的一些关于token删除的操作
// 返回拒绝态的Promise实例
return Promise.reject(new Error('token过期'))
} else {
// 其它失败状态
const { code, msg } = response.data
// 返回失败态的Promise实例,并携带错误信息
return Promise.reject({
code,
msg
})
}
}
)
5 Axios项目使用
前端在开发过程中,如果直接使用axios发送请求,大概率出现跨域问题,要了解跨域问题和解决方案,首先就需要了解同源策略:
5.1 跨域问题
5.1.1 同源策略与跨域问题
(1)同源策略
首先声明同源策略是浏览器的行为策略。
同源策略:同源是指浏览器 发出的请求所访问的服务器的url协议一样、域名一样、端口号一样,三者都一样则称为同源。
(2)跨域问题
跨域问题:同源的三个条件只要有一个不一样就是跨域,这是浏览器禁止的行为,浏览器出于安全考虑,采用同源策略,不允许跨域请求。
理解跨域问题的核心是理解浏览器发送请求的行为流程 :这里的浏览器的同源策略是对前端JS代码的约束 ,浏览器通过地址栏输入URL访问前端静态资源是允许的 。而浏览器获取从前端服务器获取到的静态资源中,JS部分访问后端服务器(不同源,和浏览器访问前端资源的URL至少端口号或域名不一样),因此才会发生跨域问题。
比如:浏览器请求前端服务器路径http://localhost:5173,前端服务器的js代码请求后端服务器路径http://localhost:8080,两者端口号不同,因此不满足同源策略。当然这种情况是前端服务器和后端服务器都部署在一台主机上,使用端口号不同。
5.1.2 跨域问题解决方案
(1)CORS:后端开启跨域资源共享,前端不需要做什么事。
(2)请求代理:浏览器访问本地服务器(这也不涉及跨域,因为这是浏览器地址栏URL的基础导航功能,并且自己访问自己凭什么不可以),由本地服务器访问后端服务器,服务器之间不存在跨域问题(因为请求链不涉及浏览器)。
5.2 代理服务器
5.2.1 三种常见场景的跨域问题

传统前后端还未完全分离的项目中,静态资源存储在后端服务器中,浏览器从后端服务器获取静态资源,静态资源中JS代码部分请求后端服务器,因此浏览器请求的URL和后端服务器URL是同源的(同协议、同域名、同端口),只是数据接口的路由地址不同,因此不存在跨域问题。
前后端分离项目,如果未配置跨域请求代理,前端静态资源部署在前端服务器中(Node服务器),浏览器请求前端静态资源,请求的URL是前端服务器的URL,而静态资源的JS部分请求的是后端服务器URL,如果前端服务器和后端服务器在同一个主机上,由于至少端口号不同,因此不同源,即发生跨域问题;如果前端服务器和后端服务器不在同一台主机上,那至少域名不相同(ip),因此也会发生跨域问题。
如果配置跨域请求代理,代理服务器也是前端服务器(仅需添加配置项),因此浏览器请求前端服务器获取静态资源,JS部分请求跨域请求代理,由跨域请求代理转发请求(服务器之间访问不存在浏览器同源策略的限制),此时就不会发生跨域问题。
5.2.2 代理服务器配置
javascript
export default defineConfig({
// 开发服务器配置
server: {
port: 80, // 端口
open: true, // 自动打开浏览器
// 配置跨域请求代理
proxy: {
'/dev-api': {
// 目前服务器地址(目前开发阶段暂时用本地ip+端口号模拟,实际应该用后端服务器的ip地址+端口号)
target: 'http://127.0.0.1:18081',
changeOrigin: true, // 改变请求头的origin源,保证到达后端服务器的值是target值而不是前端请求路径
// 路径重写:不进行重写,请求到达后端就是:服务器地址+/dev-api+请求的接口地址
// 如果后端服务器的接口地址没有/dev-api,就会请求不到资源,因此需要替换为空字符串
rewrite: (path) => path.replace(/^\/dev-api/, '')
}
}
}
})
在vite.config.js中配置Node服务器server,port是前端服务器的端口,open是启动项目自动打开首页策略。
proxy是跨域请求代理的配置项,配置转发路由为/dev-api,target是后端服务器地址,changeOrigin为true表示改变请求头的origin源,确保后端接收的请求的目标URL是后端服务器的值而不是前端发出的值。rewrite表示对路径进行重写,去除/dev-api路由。
即完整的流程如下:
(1)前端服务器位于http://localhost:80,浏览器请求静态资源的URL为http:localhost:80/example/api(前端服务器地址+JS请求后端的接口路由)。
(2)JS部分的Axios在请求路径添加http:localhost:80/dev-api/example/api发送到代理服务器(Node服务器监听80端口,如果请求路径是/dev-api,则由代理服务器处理该URL)。
(3)后端服务器位于http://localhost:18081,**代理服务器重写请求URL为http://localhost:18081/example/api并转发该请求**,因此解决跨域请求问题。
5.3 封装使用流程
由于Axios的使用流程比较固定,且每个前端涉及到请求后端的项目中都需要上述配置,因此可以对这部分进行封装,所有的项目都可以按照统一流程处理和使用:
5.3.1 axios实例封装
创建js文件,配置如下内容:
(1)导入Axios并创建实例:即全局统一配置部分;
(2)配置实例的拦截器;
(3)导出Axios实例。
5.3.2 代理服务器封装
即5.2.2代理服务器配置部分,在vite.config.js文件添加。
5.3.3 请求接口方法封装
创建api包,内部放js文件,文件内容是发送请求的方法。比如登录请求:
javascript
export const loginApi = ({ phone, password }) => {
return request({
method: 'post',
url: '/admin/sys_user/login/password',
data: {
phone,
password
}
})
}
使用该方法就在对应的组件中导入该方法,传入参数即可发送请求。