彻底掌握 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,将使你更全面地掌握前端网络通信原理,构建更健壮的交互应用。

相关推荐
轻闲一号机16 分钟前
【机器学习】机器学习笔记
人工智能·笔记·机器学习
天天扭码27 分钟前
零基础 | 入门前端必备技巧——使用 DOM 操作插入 HTML 元素
前端·javascript·dom
天下琴川1 小时前
Dify智能体平台源码二次开发笔记(5) - 多租户的SAAS版实现(2)
人工智能·笔记
咖啡虫1 小时前
css中的3d使用:深入理解 CSS Perspective 与 Transform-Style
前端·css·3d
拉不动的猪1 小时前
设计模式之------策略模式
前端·javascript·面试
旭久1 小时前
react+Tesseract.js实现前端拍照获取/选择文件等文字识别OCR
前端·javascript·react.js
独行soc1 小时前
2025年常见渗透测试面试题-红队面试宝典下(题目+回答)
linux·运维·服务器·前端·面试·职场和发展·csrf
uhakadotcom2 小时前
Google Earth Engine 机器学习入门:基础知识与实用示例详解
前端·javascript·面试
麓殇⊙2 小时前
Vue--组件练习案例
前端·javascript·vue.js
outstanding木槿2 小时前
React中 点击事件写法 的注意(this、箭头函数)
前端·javascript·react.js