axios面试题及答案全解析
从源码原理到工程化实战,深度剖析前端最流行的HTTP通信库。涵盖拦截器、取消请求、CORS跨域及错误处理等高频考点。
一、为什么面试必问 axios?
在现代前端开发中,axios 已经取代了 jQuery AJAX 成为了事实上的标准 HTTP 客户端。在面试中,考察 axios 不仅是为了验证开发者是否掌握基本的网络请求,更是为了考察其对 HTTP 协议、异步编程(Promise/Async/Await)、以及工程化配置(如拦截器、实例隔离)的理解深度。
与原生 fetch API 相比,axios 提供了更强大的功能特性,包括请求/响应拦截、自动转换 JSON 数据、客户端防止 CSRF 攻击、请求取消等。这些特性使得它在处理复杂的企业级应用需求时显得尤为关键。
⚙️ 浏览器端支持
在浏览器中发送 XMLHttpRequests,兼容性好,支持旧版本浏览器。
⚙️ Node.js 支持
在 Node.js 中发送 http 请求,使得同构应用(SSR)成为可能。
⚙️ 拦截器机制
允许在请求或响应被 then 或 catch 处理前拦截它们,是全局配置的核心。
⚙️ 请求取消
支持使用 CancelToken 取消请求,有效防止内存泄漏和无效的网络请求。
二、axios 基础 API 与请求方式
掌握 axios 的基础用法是回答面试题的前提。面试官通常会要求手写一个简单的请求,或者询问不同请求方法的区别。
1. 常用的请求方法
axios 提供了所有 HTTP 方法的别名,包括 get, post, put, patch, delete 等。
// 1. GET 请求:获取数据
axios.get('/user?ID=12345')
.then(response => console.log(response))
.catch(error => console.log(error));
// 2. POST 请求:提交数据
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(response => console.log(response))
.catch(error => console.log(error));
// 3. 请求配置对象(推荐写法)
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
2. 并发请求处理
在实际业务中,经常需要同时发起多个请求,等待所有请求完成后再进行渲染。axios 提供了 axios.all 和 axios.spread 来处理这种情况,这与 Promise.all 类似。
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
console.log(acct.data, perms.data);
}));
注意: 在较新的 ES6 环境中,通常直接使用 await Promise.all([...]) 会更加简洁和现代。
三、核心考点:拦截器(Interceptors)
拦截器是 axios 面试中的“重头戏”。它允许你在请求发出前或响应返回前修改它们,是实现全局错误处理、Token 注入、Loading 状态控制的关键。
1. 请求拦截器
用于在每次请求发送前自动添加 Token,或者打印请求日志。
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
console.log('Request Config:', config);
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
2. 响应拦截器
用于统一处理后端返回的错误码(如 401 未授权,500 服务器错误),避免在每个请求中重复编写错误判断逻辑。
axios.interceptors.response.use(function (response) {
// 2xx 范围内的状态码都会触发该函数
// 对响应数据做点什么
return response.data; // 直接返回数据体,简化后续调用
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数
// 对响应错误做点什么
if (error.response.status === 401) {
// 跳转到登录页
window.location.href = '/login';
}
return Promise.reject(error);
});
💡 面试题:如何移除拦截器?
使用 axios.interceptors.eject(id) 方法,传入拦截器的 ID 即可移除。ID 是在注册拦截器时返回的。
💡 面试题:拦截器的执行顺序?
请求拦截器按注册顺序执行;响应拦截器按注册逆序执行(LIFO)。
四、高级功能:请求取消(CancelToken)
在单页应用(SPA)中,如果用户快速切换页面或组件,之前发出的请求可能还未返回,导致数据错乱或内存泄漏。axios 提供了两种方式来取消请求。
1. 使用 CancelToken(传统方式)
通过 axios.CancelToken.source 创建一个 source 对象,其中包含 token 和 cancel 方法。
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
// 取消请求(消息参数是可选的)
source.cancel('Operation canceled by the user.');
2. 使用 AbortController(现代推荐)
随着浏览器标准的发展,推荐使用原生的 AbortController API,它与 axios 完美兼容,且更符合现代 Web 标准。
const controller = new AbortController();
axios.get('/user/12345', {
signal: controller.signal
}).then(response => {
console.log(response);
});
// 取消请求
controller.abort();
面试提示: 面试官可能会问为什么需要取消请求?答案通常包括:节省带宽、防止内存泄漏、避免在组件卸载后更新状态(React 警告)。
五、axios 实例创建与全局配置
在大型项目中,通常不会直接使用默认的 axios 实例,而是创建多个实例来管理不同的 API 服务(如:用户服务、支付服务、第三方服务)。
1. 创建实例
使用 axios.create() 可以创建一个新的实例,它继承了默认实例的配置,但可以单独覆盖。
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
// 该实例的默认配置
console.log(instance.defaults.timeout); // 1000
2. 配置选项详解
| 配置项 | 说明 | 默认值 |
|---|---|---|
| url | 用于请求的 URL | / |
| method | 请求方法 | get |
| baseURL | 如果 url 是相对路径,将自动拼接此地址 | '' |
| timeout | 请求超时时间(毫秒) | 0 (无限) |
| withCredentials | 表示跨域请求是否需要凭证 | false |
| adapter | 允许自定义处理请求 | 使默认 http 适配器 |
六、错误处理与网络异常
健壮的应用必须具备良好的错误处理能力。axios 的错误对象包含丰富的信息,如 error.message, error.response, error.request。
1. 错误对象结构
- error.response:服务器已响应,但状态码在 2xx 之外。包含
status,headers,data等详细信息。 - error.request:请求已发出,但未收到响应。在浏览器中是 XMLHttpRequest 实例,在 Node.js 中是 http.ClientRequest 实例。
- error.message:描述错误的消息。
axios.get('/user/12345')
.catch(function (error) {
if (error.response) {
// 请求已发出,服务器返回非 2xx 状态
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// 请求已发出,但没有收到响应
console.log(error.request);
} else {
// 在设置请求时发生了一些事情,触发了一个错误
console.log('Error', error.message);
}
console.log(error.config);
});
2. 全局错误处理
结合响应拦截器,可以实现全局的 Toast 提示或日志上报。
七、进阶:axios 底层原理与源码解析
对于高级前端岗位,面试官可能会询问 axios 的底层实现。axios 的核心是基于 XMLHttpRequest (浏览器) 和 http (Node.js) 封装的,并且使用了 Promise API。
1. 核心流程
调用 axios(url) 或 axios(config),进入核心方法 dispatchRequest。
遍历 requestInterceptors,执行每个拦截器的 use 方法中的第一个回调(onFulfilled)。
根据环境(浏览器/Node)调用对应的适配器(xhr.js 或 http.js),发起真实的网络请求。
请求完成后,遍历 responseInterceptors,执行回调(注意是逆序)。
最终返回处理后的数据或错误。
2. axios 与 fetch 的区别
数据转换
axios 自动将 JSON 数据转换为 JavaScript 对象;fetch 默认不会转换,需手动调用 .json()。
错误处理
axios 在网络错误和 HTTP 错误(4xx/5xx)都会进入 catch;fetch 只有网络错误进入 catch,HTTP 错误需手动判断 response.ok。
请求取消
axios 原生支持 CancelToken;fetch 需要借助 AbortController。
浏览器支持
axios 兼容 IE;fetch 不支持 IE。
九、总结
通过本文对 axios面试题及答案 的全面解析,相信您已经对 axios 的核心功能、底层原理以及常见面试题有了深入的理解。从基础的 GET/POST 请求,到复杂的拦截器配置,再到请求取消和错误处理,每一个环节都是前端工程化能力的体现。
记住,面试不仅是考察知识点的记忆,更是考察解决问题的思路。在实际工作中,合理运用 axios 的特性,编写出健壮、可维护、高性能的网络请求代码,才是最终的目标。希望这份指南能帮助您在面试中脱颖而出,也希望您能继续关注 kamiacca.cn 获取更多前沿技术资讯。