广告

JavaScript发送AJAX请求的几种实现方式解析(XHR、Fetch、Axios等对比)

1. XHR(XMLHttpRequest)实现原理与应用

1.1 基本工作原理

在浏览器端,XMLHttpRequest(XHR)是最早实现 JavaScript 发送 AJAX 请求的核心对象,它通过异步向服务器发起 HTTP 请求,并在回调中处理响应。open 用来设置请求方式、地址与是否异步,send 发送请求体,onreadystatechange 会在状态改变时触发,readyState 的取值 0~4 表示从未开启到完成,status 表示 HTTP 状态码。对历史兼容性较强的项目,XHR 仍然是底层实现的主力。

该模式的实现要点包括:先创建对象、配置方法和地址、发送请求、接收响应并按阶段处理。跨域请求和证书校验等安全机制也是设计时需要关注的要点。

1.2 常见用法示例

下面给出一个简单的 GET 请求示例,展示 XHR 的典型流程和错误处理要点。错误处理和数据解析是此实现的关键。

JavaScript发送AJAX请求的几种实现方式解析(XHR、Fetch、Axios等对比)

var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', true);
xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status === 200) {var data = JSON.parse(xhr.responseText);console.log(data);} else {console.error('请求失败,状态码:' + xhr.status);}}
};
xhr.send();

如果需要发送 POST 请求,可以在发送前设置请求头并将数据放到 send 的参数中。content-typeJSON 序列化 常伴随出现。

1.3 优缺点与应用要点

优点在于广泛的浏览器兼容性与对底层网络事件的细粒度控制,适合需要逐步处理响应、显示进度或在老旧浏览器中保持稳定的场景。缺点是代码可读性较低、错误处理分散,以及新特性支持(如 Promise、拦截器)需要额外封装。

要点总结包括:确保正确处理 readyState 的四个阶段、对异常状态码做统一处理、以及在跨域场景下合理设置 withCredentials 与 CORS 头部。

2. Fetch API 的实现方式

2.1 基本用法

在现代浏览器中,Fetch API 提供基于的异步请求,语法更加简洁、流程更易于组合,且天然支持流式响应。与 XHR 相比,代码结构更清晰,便于与 async/await 结合。

Fetch 将请求发出后返回一个 Response 对象,开发者需要自行处理 response.okresponse.json() 等状态与数据转换。

fetch('/api/data').then(function (response) {if (!response.ok) {throw new Error('网络响应不正常,状态码:' + response.status);}return response.json();}).then(function (data) {console.log(data);}).catch(function (error) {console.error('Fetch 错误:', error);});

2.2 POST 请求与错误处理

Post 请求需要设置请求头并将请求体序列化为 JSON,Fetch 提供简单的选项对象来完成此操作,Content-Type 常被设置为 application/json

fetch('/api/update', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ id: 123, value: 'new' })
})
.then(function (response) {if (!response.ok) throw new Error('请求失败: ' + response.status);return response.json();
})
.then(function (data) {console.log(data);
})
.catch(function (error) {console.error('请求错误:', error);
});

2.3 超时与跨域处理

Fetch 原生并不提供超时控制,需要借助 AbortController、定时器等手段实现。跨域请求要关注 CORS 策略与凭证发送。

const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);fetch('/api/data', { signal: controller.signal }).then(r => r.json()).then(data => console.log(data)).catch(err => console.error('请求错误或超时:', err)).finally(() => clearTimeout(timeout));

3. Axios 的实现方式

3.1 安装与引入

Axios 是一个独立的 HTTP 客户端库,跨浏览器与 Node.js 环境都可使用。它提供统一的 API、拦截器、默认对 JSON 处理等特性。安装方式包括通过 npm/yarn 或在网页中直接引入 CDN 脚本。

// 使用 npm 安装
// npm install axios
import axios from 'axios';
axios.get('/api/data').then(res => console.log(res.data));
// 通过 CDN 使用(浏览器全局 axios)
// 
axios.get('/api/data').then(res => console.log(res.data));

3.2 常用用法

Axios 的请求方法覆盖了常见的 REST 场景,自动转换 JSON错误抛错行为、以及对请求/响应头的灵活控制。

axios.get('/api/data').then(function (response) {console.log(response.data);}).catch(function (error) {console.error('Axios 错误:', error);});

3.3 拦截器与全局配置

通过 拦截器,可以在请求发送前统一添加认证信息、统一处理响应错误等,全局配置(如 baseURL、超时、头部)使得代码更加整洁。

// 请求拦截器
axios.interceptors.request.use(function (config) {config.headers.Authorization = 'Bearer token';return config;
}, function (error) {return Promise.reject(error);
});// 响应拦截器
axios.interceptors.response.use(function (response) {return response;
}, function (error) {return Promise.reject(error);
});

3.4 取消请求

Axios 提供了取消机制,便于在组件卸载或用户取消操作时中断请求。常用方式包括 CancelToken(部分版本仍在使用)和对 AbortController 的兼容。

const source = axios.CancelToken.source();
axios.get('/api/data', { cancelToken: source.token }).catch(function (thrown) {if (axios.isCancel(thrown)) {console.log('请求被取消', thrown.message);} else {console.error(thrown);}});// 取消请求
source.cancel('用户取消');

4. XHR、Fetch、Axios 的对比与选型

4.1 对比要点

三者在 API 设计、错误处理和生态方面存在明显差异。XHR依赖回调机制,适合兼容性很重要的场景;Fetch基于 Promise,语法更现代,易于与 async/await 组合,但需要自行处理超时、取消等场景;Axios在 Promise 基础上提供了拦截器、基于配置的默认行为、以及对 Node 环境的原生支持,减少重复代码。

关于错误处理,Fetch 需要通过检查 response.ok 来区分网络错误与 HTTP 错误;Axios 对错误对象提供统一的封装,方便捕获。 取消请求方面,Fetch 使用 AbortController,而 Axios 提供了自己的取消机制,二者可以根据项目技术栈进行选择。

4.2 适用场景与生态考量

在需要向后兼容性极高的旧代码库、或必须手工处理每个网络事件的场景,XHR 仍有优势。对现代单页应用而言,Fetch+async/await 提供简洁的代码结构;若项目需要统一的请求配置、拦截器、以及在 Node 环境中也可直接使用的能力,Axios成为更高效的选择。

生态与依赖方面,XHR 与 Fetch 属于浏览器内置能力,无额外依赖;Axios 作为第三方库,会引入额外的 bundle 大小,但带来的拦截器、取消、全局配置等特性往往能显著提升开发效率。

4.3 结合示例的对比要点

用一个简单的 GET 请求对比三者的表达方式:XHR 需要写较多的就绪处理逻辑,Fetch 以 Promise 链式调用实现,Axios 则提供了最简洁的调用方式并可通过拦截器扩展。

// XHR 示例
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/data', true);
xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log(JSON.parse(xhr.responseText));}
};
xhr.send();
// Fetch 示例
fetch('/api/data').then(r => r.ok ? r.json() : Promise.reject('Error: ' + r.status)).then(console.log).catch(console.error);
// Axios 示例
axios.get('/api/data').then(res => console.log(res.data)).catch(console.error);

广告