```html
欢迎访问 kaoacca.cn - 专注前端技术分享与面试题解析

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. 错误对象结构

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. 核心流程

Step 1: 入口

调用 axios(url) 或 axios(config),进入核心方法 dispatchRequest。

Step 2: 请求拦截器

遍历 requestInterceptors,执行每个拦截器的 use 方法中的第一个回调(onFulfilled)。

Step 3: 适配器(Adapter)

根据环境(浏览器/Node)调用对应的适配器(xhr.js 或 http.js),发起真实的网络请求。

Step 4: 响应拦截器

请求完成后,遍历 responseInterceptors,执行回调(注意是逆序)。

Step 5: 返回 Promise

最终返回处理后的数据或错误。

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 获取更多前沿技术资讯。

```
斌知网
蜀ICP备2026017620号-5