You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何克隆XMLHttpRequest对象?两种尝试方案及报错解析

克隆已配置的XMLHttpRequest对象

需求场景

需要克隆一个已完成配置(调用过open和setRequestHeader)的XMLHttpRequest对象,原代码如下:

let xhr = new XMLHttpRequest;
xhr.open('GET', '/', true);
xhr.setRequestHeader('Test', 'test');

let clone = ....?
xhr.send();

clone.setRequestHeader('Test2', '....');
clone.send();

失败尝试与问题分析

尝试方案1

let xhr = new XMLHttpRequest;
xhr.open('GET', '/', true);
xhr.setRequestHeader('Test', 'test');

let clone = Object.assign(Object.create(Object.getPrototypeOf(xhr)), xhr);
xhr.send();

clone.setRequestHeader('Test2', '....');
clone.send();

报错信息(翻译后):

Uncaught TypeError: 在未实现XMLHttpRequest接口的对象上调用了'setRequestHeader'方法。

问题原因:
XMLHttpRequest是浏览器提供的原生宿主对象,其内部接口和状态无法通过Object.create+Object.assign的方式模拟。这种方法创建的对象仅继承了XHR的原型结构,并非真正的XMLHttpRequest实例,因此无法调用其原生方法。

尝试方案2

let xhr = new XMLHttpRequest;
xhr.open('GET', '/', true);
xhr.setRequestHeader('Test', 'test');

let clone = new XMLHttpRequest;
Object.assign(clone, xhr);
xhr.send();

clone.setRequestHeader('Test2', '....');
clone.send();

报错信息(翻译后):

Uncaught DOMException: XMLHttpRequest.setRequestHeader: XMLHttpRequest的状态必须是OPENED。

问题原因:
Object.assign仅能复制XHR对象的可枚举属性,但XMLHttpRequest的内部状态(如是否执行过open)属于不可枚举的私有属性,无法通过此方式复制。新创建的clone实例未执行open方法,状态未进入OPENED阶段,因此调用setRequestHeader会触发报错。

正确解决方案

XMLHttpRequest实例的内部状态无法直接克隆,可靠的方式是抽离请求配置逻辑,用统一的配置对象初始化多个XHR实例:

// 抽离请求配置
const requestConfig = {
  method: 'GET',
  url: '/',
  async: true,
  headers: {
    'Test': 'test'
  }
};

// 初始化原XHR并发送
const xhr = new XMLHttpRequest;
xhr.open(requestConfig.method, requestConfig.url, requestConfig.async);
for (const [key, value] of Object.entries(requestConfig.headers)) {
  xhr.setRequestHeader(key, value);
}
xhr.send();

// 克隆配置并初始化新XHR
const clone = new XMLHttpRequest;
clone.open(requestConfig.method, requestConfig.url, requestConfig.async);
// 复制原请求头
for (const [key, value] of Object.entries(requestConfig.headers)) {
  clone.setRequestHeader(key, value);
}
// 添加新请求头
clone.setRequestHeader('Test2', 'new-value');
clone.send();

补充说明

由于XMLHttpRequest API未提供直接获取已设置请求头的方法,无法从已配置的XHR实例中反向提取完整配置。因此提前封装配置对象,是实现“配置复用/克隆”的最优方案。

内容的提问来源于stack exchange,提问作者Ivan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:57:19