XMLHttpRequest 对象

XMLHttpRequest(XHR)对象最全速查表(2025 版)

—— 虽然现在大家都用 fetch,但面试、老项目、理解底层原理时它仍然是王者!

项目内容 / 写法(2025 推荐)必背度
创建对象const xhr = new XMLHttpRequest();★★★★★
打开请求xhr.open(method, url, async=true, user=null, password=null)★★★★★
发送请求xhr.send(body)(GET 传 null 或省略,POST 传数据)★★★★★
监听状态变化xhr.onreadystatechange = function() { if (xhr.readyState === 4) { … } }★★★★
推荐监听方式(现代)xhr.onload = () => { … } xhr.onerror = () => { … }★★★★★
超时设置xhr.timeout = 5000; xhr.ontimeout = () => { … }★★★★★
响应类型xhr.responseType = "json" | "text" | "document" | "blob" | "arraybuffer"★★★★★
取响应文本xhr.responseText(老项目)★★★★
取响应(推荐)xhr.response(配合 responseType 使用,自动解析)★★★★★
状态码xhr.status(200、404、500 等)★★★★★
状态文本xhr.statusText(”OK”、”Not Found”)★★★★
readyState 值0=未初始化 1=OPENED 2=HEADERS_RECEIVED 3=LOADING 4=DONE★★★★★

2025 年最推荐的完整写法(直接复制用)

function xhrRequest({ method = "GET", url, data = null, timeout = 10000, responseType = "json" } = {}) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();

    xhr.responseType = responseType;   // 关键!让 response 自动解析
    xhr.timeout = timeout;

    xhr.onload = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(xhr.response);        // 自动是对象(json)或文本
      } else {
        reject(new Error(`HTTP ${xhr.status} ${xhr.statusText}`));
      }
    };

    xhr.onerror = () => reject(new Error("网络错误"));
    xhr.ontimeout = () => reject(new Error("请求超时"));

    xhr.open(method, url, true);        // async 永远 true
    if (method === "POST" || method === "PUT") {
      xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    }

    xhr.send(data ? JSON.stringify(data) : null);
  });
}

// 使用(和 fetch 几乎一样爽)
xhrRequest({ url: "/api/books" })
  .then(data => console.log(data))
  .catch(err => console.error(err));

xhrRequest({ 
  method: "POST", 
  url: "/api/books", 
  data: { title: "三体" }
}).then(res => console.log("添加成功", res));

经典老写法(面试必会)

const xhr = new XMLHttpRequest();
xhr.open("GET", "books.xml", true);

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {           // 请求完成
    if (xhr.status === 200) {
      console.log(xhr.responseXML);     // XML 文档
      console.log(xhr.responseText);    // 原始字符串
    } else {
      console.error("错误", xhr.status);
    }
  }
};

xhr.send();   // GET 不传参数

XHR vs Fetch 终极对比(2025 结论)

项目XMLHttpRequestFetch API(2025 推荐)
是否 Promise否(要自己包)原生 Promise
超时控制xhr.timeout(好用)需要 AbortController
上传进度xhr.upload.onprogress(完美)支持,但写法稍复杂
响应类型自动解析xhr.response + responseType(好用)res.json()res.text()
取消请求xhr.abort()AbortController
兼容性IE9+(包括 IE)IE 全灭,现代浏览器 100%
老项目/面试必会必会
新项目推荐只在需要上传进度时用99% 情况用 fetch

2025 年最终结论(一句话记住)

  • 新项目:99% 用 fetchaxios
  • 必须用 XHR 的 3 个场景:
  1. 需要上传/下载进度条(xhr.upload.onprogress
  2. 老项目维护(IE、企业内网)
  3. 面试被问底层原理

背会上面那段 Promise 封装的 xhrRequest 函数 + 经典老写法,
你就已经完全掌握了 XMLHttpRequest,面试、企业项目、底层原理三不误!

需要我给你一个「XHR + Fetch + Axios 三套代码实时对比演示页面」,随时说一声~

文章已创建 2732

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部