知识篇 -- JS网络请求:数据交互
Ray Shine
2024/2/17 JavaScript进阶知识网络请求HTTP
本文为博主原创文章,遵循
CC 4.0 BY-SA
版权协议,转载请附上原文出处链接和本声明。
如有侵权,请联系
本博主
删除。
在现代Web应用中,前端与后端的数据交互是不可或缺的一部分。JavaScript提供了多种机制来实现网络请求,从传统的 XMLHttpRequest 到现代的 Fetch API,再到流行的第三方库 Axios。理解这些网络请求方式的特点、用法和最佳实践,是构建动态、数据驱动型Web应用的关键。
# 一、XMLHttpRequest (XHR):传统请求方式 传统
XMLHttpRequest 是一个JavaScript对象,用于在后台与服务器交换数据。它是Ajax(Asynchronous JavaScript and XML)技术的核心。
- 特点:
- 老牌:兼容性好,几乎所有浏览器都支持。
- 事件驱动:通过监听不同的事件(如
onload,onerror,onprogress)来处理请求的各个阶段。 - 配置复杂:API相对底层,需要手动设置请求头、处理状态码等。
- 回调地狱:在处理多个串联请求时,容易陷入回调地狱。
- 基本用法:
const xhr = new XMLHttpRequest(); xhr.open("GET", "https://api.example.com/data", true); // true表示异步 xhr.timeout = 2000; // 设置超时时间 xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { console.log("请求成功:", JSON.parse(xhr.responseText)); } else { console.error("请求失败:", xhr.status, xhr.statusText); } }; xhr.onerror = function() { console.error("网络错误或请求被阻止。"); }; xhr.ontimeout = function() { console.error("请求超时。"); }; xhr.send(); // 发送请求 - 发送POST请求:
xhr.open("POST", "https://api.example.com/submit", true); xhr.setRequestHeader("Content-Type", "application/json"); // 设置请求头 xhr.send(JSON.stringify({ key: "value" })); // 发送JSON数据
# 二、Fetch API:现代Web请求标准 (ES6新增) 现代
Fetch API 提供了 XMLHttpRequest 的所有功能,但设计更简洁、更强大,并且基于Promise,使得异步请求的处理更加优雅。
- 特点:
- 基于Promise:天然支持
async/await,解决了回调地狱问题。 - API简洁:更符合现代JavaScript的编程风格。
- 流式处理:支持流式读取响应体。
- 默认不发送Cookie:需要手动设置
credentials: 'include'。 - 错误处理:
fetch只有在网络错误或请求被阻止时才rejectPromise。对于HTTP错误状态码(如404, 500),Promise仍然会resolve,但response.ok会是false。
- 基于Promise:天然支持
- 基本用法:
fetch("https://api.example.com/data") .then(response => { if (!response.ok) { // 检查HTTP状态码 throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); // 解析JSON响应体 }) .then(data => { console.log("请求成功:", data); }) .catch(error => { console.error("请求失败:", error); }); - 发送POST请求:
fetch("https://api.example.com/submit", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key: "value" }) }) .then(response => response.json()) .then(data => console.log("提交成功:", data)) .catch(error => console.error("提交失败:", error)); - 使用
async/await:async function fetchDataAsync() { try { const response = await fetch("https://api.example.com/data"); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log("请求成功:", data); } catch (error) { console.error("请求失败:", error); } } fetchDataAsync();
# 三、Axios:流行的第三方HTTP客户端 第三方库
Axios 是一个基于Promise的HTTP客户端,可以在浏览器和Node.js环境中使用。它在 XMLHttpRequest 或 http 模块的基础上进行了封装,提供了更强大的功能和更友好的API。
- 特点:
- 基于Promise:支持
async/await。 - 自动转换JSON数据:请求和响应数据会自动进行JSON转换。
- 拦截器:支持请求和响应拦截器,方便统一处理请求头、错误等。
- 取消请求:支持取消请求。
- 客户端防御XSRF:提供了一些安全特性。
- 兼容性:支持旧版浏览器。
- 基于Promise:支持
- 安装:
npm install axios或yarn add axios - 基本用法:
// GET请求 axios.get("https://api.example.com/data") .then(response => { console.log("请求成功:", response.data); // response.data直接就是解析后的JSON }) .catch(error => { console.error("请求失败:", error); }); // POST请求 axios.post("https://api.example.com/submit", { key: "value" // Axios会自动将其转换为JSON }) .then(response => { console.log("提交成功:", response.data); }) .catch(error => { console.error("提交失败:", error); }); - 使用
async/await:async function fetchDataAxios() { try { const response = await axios.get("https://api.example.com/data"); console.log("请求成功:", response.data); } catch (error) { console.error("请求失败:", error); if (error.response) { // 请求已发出,但服务器响应的状态码不在 2xx 范围内 console.error("响应数据:", error.response.data); console.error("响应状态:", error.response.status); console.error("响应头:", error.response.headers); } else if (error.request) { // 请求已发出,但没有收到响应 console.error("没有收到响应:", error.request); } else { // 在设置请求时发生了其他错误 console.error("其他错误:", error.message); } } } fetchDataAxios(); - 拦截器示例:
// 请求拦截器 axios.interceptors.request.use(config => { // 在发送请求之前做些什么 config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`; return config; }, error => { // 对请求错误做些什么 return Promise.reject(error); }); // 响应拦截器 axios.interceptors.response.use(response => { // 对响应数据做些什么 return response; }, error => { // 对响应错误做些什么 if (error.response.status === 401) { // 处理认证失败 console.log("认证失败,请重新登录。"); } return Promise.reject(error); });
# 四、总结
JavaScript网络请求是前端开发中与后端交互的桥梁。从传统的 XMLHttpRequest 到现代的 Fetch API,再到功能强大的 Axios 库,每种方式都有其独特的优势。在现代项目中,Fetch API 和 Axios 是主流选择,它们提供了基于Promise的异步处理能力,使得网络请求的代码更加简洁、可读和易于维护。合理选择和运用这些工具,能够帮助你高效地构建数据驱动的Web应用。