彻底掌握 XMLHttpRequest(XHR):前端通信的基石

一、XHR 的起源与演进

1.1 技术背景

XHR(XMLHttpRequest)是现代 Web 应用的异步通信基石,最早由微软在 IE5 中通过 ActiveXObject 引入,后来被 Mozilla 推广并成为 W3C 的标准接口。XHR 的出现推动了 AJAX(Asynchronous JavaScript and XML)技术的兴起,使得网页可以在不刷新页面的情况下与服务器进行数据交互。

1.2 演进历程

XHR 虽已被 Fetch、Axios 等现代 API 所部分取代,但其仍在兼容性处理、老旧系统维护和底层封装中具有重要地位。

二、XHR 的运行机制

2.1 基本工作流程

XHR 的运行基于以下步骤:

2.2 请求状态详解

XHR 的 readyState 属性定义了XMLHttpRequest生命周期中的五个阶段,开发者可以据此精确控制异步通信逻辑:

各状态说明:

0: UNSENT(未初始化)

  • 请求未初始化,尚未调用.open()方法。

1: OPENED(已建立连接)

已调用.open()方法,但尚未调用 .send()。此时可以设置请求头信息。适合做以下操作:

  • xhr.setRequestHeader(...)

  • 绑定 onreadystatechange 等事件监听器

2: HEADERS_RECEIVED(已接收响应头)

send() 已被调用,响应头已经接收完成,可以使用:

  • xhr.getAllResponseHeaders()

  • xhr.getResponseHeader("Content-Type") 等方法

3: LOADING(正在接收响应体)

浏览器正在下载响应体数据(如果响应较大可多次触发)。可用于:

  • 监听进度(onprogress

  • 构建流式数据加载方案(如大文件处理)

4: DONE(请求已完成)

响应数据全部接收完成。此时可以访问:

  • xhr.responseText(默认)

  • 或根据 responseType 访问 xhr.response(如 blob, arraybuffer, json


三、XHR 接口与 API 详解

3.1 常用方法

方法名 功能说明
open(method, url, async) 初始化请求
send(data) 发送请求体
setRequestHeader(name, value) 设置 HTTP 请求头
abort() 中止请求
getResponseHeader(name) 获取指定响应头
getAllResponseHeaders() 获取所有响应头

3.2 常用属性

属性名 描述
readyState 请求状态(0-4)
status 响应状态码(如 200)
statusText 状态描述文字(如 OK)
responseText 返回的纯文本数据
responseXML 返回的 XML 数据
response 返回值,格式依据 responseType
timeout 请求超时时间(ms)

3.3 事件处理器

事件名 描述
onreadystatechange readyState 改变时触发
onload 请求成功完成触发
onerror 请求出错时触发
ontimeout 请求超时时触发

四、使用实例与实战技巧

4.1 GET 请求示例

javascript 复制代码
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/data", true);
xhr.onload = () => {
  if (xhr.status === 200) {
    console.log(xhr.responseText);
  }
};
xhr.send();

4.2 POST 请求(发送 JSON)

javascript 复制代码
const xhr = new XMLHttpRequest();
xhr.open("POST", "/submit", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = () => {
  if (xhr.status === 200) {
    console.log("成功:", xhr.responseText);
  }
};
xhr.send(JSON.stringify({ username: "alice" }));

4.3 表单上传

javascript 复制代码
const formData = new FormData();
formData.append("file", fileInput.files[0]);

const xhr = new XMLHttpRequest();
xhr.open("POST", "/upload", true);
xhr.onload = () => console.log(xhr.responseText);
xhr.send(formData);

五、异常处理、安全与跨域

5.1 网络错误与超时

javascript 复制代码
xhr.onerror = () => console.error("请求失败");
xhr.timeout = 3000;
xhr.ontimeout = () => alert("超时");

5.2 状态码判断

javascript 复制代码
if (xhr.status >= 200 && xhr.status < 300) {
  console.log("成功响应");
} else {
  console.error("失败状态码:", xhr.status);
}

5.3 跨域请求(CORS)

html 复制代码
// 服务器响应头
Access-Control-Allow-Origin: *

5.4 安全建议

  • 始终使用 HTTPS

  • 实现 CSRF Token 检查

  • 设置 SameSite Cookie 限制


六、XHR 的现代比较与总结

6.1 与 Fetch API 对比

特性 XHR Fetch
Promise 支持
拦截器支持 可封装实现
请求取消 abort() 支持 AbortController
响应流处理 不支持 支持
兼容性

6.2 与框架集成

  • jQuery:$.ajax() 内部使用 XHR

  • Axios:封装自 XHR,支持拦截器和Promise

  • Vue/React:推荐使用 Fetch/Axios,但也可自定义封装 XHR

6.3 性能优化建议

  • 使用连接池或请求复用技术

  • 减少无效请求,使用缓存策略

  • 合理设置 timeout 与重试机制

  • 分批加载与分页


结语

尽管现代 Web 通信趋向使用 Fetch 和第三方库,XHR 依旧是理解异步通信与浏览器工作机制的基础。它不仅在老项目维护中仍然重要,也是许多框架封装逻辑的底层实现。

精通 XHR,将使你更全面地掌握前端网络通信原理,构建更健壮的交互应用。

相关推荐
虾球xz3 小时前
游戏引擎学习第268天:合并调试链表与分组
c++·学习·链表·游戏引擎
Y3174294 小时前
Python Day23 学习
python·学习
song_ly0015 小时前
深入理解软件测试覆盖率:从概念到实践
笔记·学习·测试
蓝婷儿5 小时前
前端面试每日三题 - Day 32
前端·面试·职场和发展
DIY机器人工房5 小时前
[6-2] 定时器定时中断&定时器外部时钟 江协科技学习笔记(41个知识点)
笔记·stm32·单片机·学习·江协科技
海尔辛6 小时前
学习黑客5 分钟小白弄懂Windows Desktop GUI
windows·学习
星空寻流年6 小时前
CSS3(BFC)
前端·microsoft·css3
九月TTS6 小时前
开源分享:TTS-Web-Vue系列:Vue3实现固定顶部与吸顶模式组件
前端·vue.js·开源
CodeCraft Studio6 小时前
数据透视表控件DHTMLX Pivot v2.1发布,新增HTML 模板、增强样式等多个功能
前端·javascript·ui·甘特图
一把年纪学编程6 小时前
【牛马技巧】word统计每一段的字数接近“字数统计”
前端·数据库·word