XMLHttpRequest 对象

XMLHttpRequest(XHR)对象 —— 现代前端的「老将」与「活化石」

虽然现在大家都用 fetch(),但 XMLHttpRequest 依然是前端面试、底层库(Axios、jQuery)、老项目、企业系统中最常见、最重要的 AJAX 技术。很多高级特性(上传进度、超时控制、Abort、同步请求等)fetch 至今仍需 polyfill,而 XHR 原生就支持。

1. 基本信息一览(2025 年最新状态)

项目值 / 说明构造函数new XMLHttpRequest()全局可用性所有浏览器(包括 IE11+) + Node.js(需 polyfill)是否过时不推荐新建(MDN 已标记为 Legacy),但仍被广泛使用替代品fetch()(推荐)唯一优势(至今不可替代)上传/下载进度、AbortController 兼容性、同步请求、FormData 上传进度等

2. 完整生命周期与事件(必须背下来的 6 个事件)

const xhr = new XMLHttpRequest();

// 1. 关键事件(按顺序触发)

xhr.onloadstart = () => console.log("开始请求");

xhr.onprogress = (e) => {

if (e.lengthComputable) {

console.log(`已接收 ${e.loaded} / ${e.total} 字节`);

}

};

xhr.onload = () => console.log("请求完成(成功或失败)");

xhr.onloadend = () => console.log("请求彻底结束");

xhr.onerror = () => console.log("网络错误");

xhr.ontimeout = () => console.log("超时");

xhr.onabort = () => console.log("手动中止");

// 2. 就绪状态变化(经典)

xhr.onreadystatechange = () => {

if (xhr.readyState === 4) { // DONE

if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {

console.log("成功", xhr.responseText);

}

}

console.log("readyState:", xhr.readyState);

// 0 UNSENT → 1 OPENED → 2 HEADERS_RECEIVED → 3 LOADING → 4 DONE

};

3. 核心属性与方法(高频面试点)

类型名称说明方法open(method, url, async?, user?, password?)初始化请求,async 默认 truesend(body?)发送请求,body 可以是 string、Document、Blob、FormData 等setRequestHeader(name, value)设置请求头(必须在 open() 之后、send() 之前)abort()中止请求,触发 onabortgetResponseHeader(name)获取单个响应头getAllResponseHeaders()获取所有响应头(字符串,\r\n 分隔)属性readyState0–4 五个状态status / statusTextHTTP 状态码和文字response响应体(根据 responseType 自动解析)responseText永远是字符串(即使出错)responseXML如果是 XML 且响应头正确,会自动解析为 DocumentresponseURL最终重定向后的 URL(非常有用)timeout超时毫秒数(0 表示永不超时)withCredentials是否发送跨域 cookie(CORS 需要)upload上传专用的 XHRUpload 对象,可监听上传进度!responseType”

4. 经典完整示例(包含所有实战技巧)

function ajax(options) {

const xhr = new XMLHttpRequest();

// 1. 基础配置

xhr.open(options.method || 'GET', options.url, true);

// 2. 超时与中止

xhr.timeout = options.timeout || 10000;

xhr.ontimeout = () => options.error?.('请求超时');

const controller = new AbortController(); // 可外部 abort

options.signal?.addEventListener('abort', () => xhr.abort());

// 3. 上传进度(FormData 上传文件必备)

if (xhr.upload && options.onProgress) {

xhr.upload.onprogress = (e) => {

if (e.lengthComputable) {

options.onProgress(e.loaded / e.total * 100);

}

};

}

// 4. 响应类型

xhr.responseType = options.responseType || 'json';

// 5. 请求头

if (options.headers) {

for (const [k, v] of Object.entries(options.headers)) {

xhr.setRequestHeader(k, v);

}

}

// 6. 跨域带 cookie

if (options.withCredentials) xhr.withCredentials = true;

// 7. 成功回调

xhr.onload = () => {

if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {

options.success?.(xhr.response, xhr);

} else {

options.error?.(new Error(xhr.statusText || 'Request failed'));

}

};

xhr.onerror = () => options.error?.(new Error('Network Error'));

// 8. 发送

xhr.send(options.data || null);

// 返回可中止的对象

return { abort: () => xhr.abort() };

}

5. 上传文件 + 进度条(唯一 fetch 至今仍麻烦的场景)

const fileInput = document.querySelector('input[type=file]');

const progress = document.querySelector('progress');

fileInput.onchange = () => {

const file = fileInput.files[0];

const xhr = new XMLHttpRequest();

xhr.open('POST', '/upload');

xhr.upload.onprogress = (e) => {

if (e.lengthComputable) {

progress.value = (e.loaded / e.total) * 100;

}

};

xhr.onload = () => alert('上传成功!');

xhr.onerror = () => alert('上传失败');

const form = new FormData();

form.append('avatar', file);

xhr.send(form);

};

6. XHR vs fetch 终极对比(2025 年版)

特性XMLHttpRequestfetch()胜者上传进度原生支持(xhr.upload)需 ReadableStream 手动实现XHR下载进度原生 onprogress需手动解析 body streamXHR超时控制原生 timeout需 AbortController + setTimeoutXHR中止请求abort()AbortController平手同步请求支持(不推荐)完全不支持XHR自动解析 JSON需手动 JSON.parseresponse.json()fetch流式处理不支持原生支持fetch跨域带 cookiewithCredentialscredentials: ‘include’平手兼容性IE11+IE 全灭,现代浏览器全支持XHR(老项目)代码简洁性复杂极简fetch

7. 总结:什么时候还得用 XHR?

场景必须用 XHR?需要显示上传进度条Yes大文件分片上传Yes老项目维护(jQuery/AngularJS)Yes需要同步请求(极少数场景)Yes企业内部系统(IE11 兼容)Yes日常 CRUD、JSON 接口推荐 fetch

一句话定论:

fetch 是未来,XHR 是现在和过去。学新项目用 fetch,面试 + 维护老项目 + 实现上传进度条 → 必须精通 XMLHttpRequest!

记住这张图,你就永远不会被 XHR 面试题难倒:

open() → setRequestHeader() → send() → onprogress → onload/onerror/ontimeout → abort()

Copyright © 2088 一键全脑游戏活动站 - 脑力挑战专属福利 All Rights Reserved.
友情链接