Request 构造函数用于创建可复用的请求实例,而非单纯复用配置;需通过 clone() 复用含 body 的 Request,避免 bodyUsed 报错;适用于 Service Worker 缓存、请求重试、多端适配与日志监控等场景。

Request 构造函数不是用来“复用配置”的工具,而是用来创建一个可复用的 请求实例。真正的复用逻辑在于:先定义好带配置的 Request 对象,再把它传给 fetch() 多次调用——但要注意,有请求体(body)的 Request 只能用一次。
用 Request 对象封装固定配置
把 URL、method、headers、credentials 等通用设置写进 init 参数,生成一个 Request 实例。它比字符串 URL 更可控,也更适合在 Service Worker、中间件或请求拦截场景中传递。
- 例如统一添加认证头和 JSON 内容类型:
const baseReq = new Request('/api/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
credentials: 'include'
});
后续可以直接 fetch(baseReq),无需重复写 headers 和 credentials。
立即学习“Java免费学习笔记(深入)”;
有 body 的 Request 必须克隆才能多次使用
如果 Request 包含 body(比如 JSON 字符串或 FormData),它的 bodyUsed 属性会在第一次 fetch() 后变为 true,再次使用会报错:TypeError: Failed to construct 'Request': Cannot construct a Request with a Request object that has already been used.
- 解决办法:每次发送前调用
.clone() -
.clone()创建完全一致的副本,且不会标记原对象的 body 为已使用
const reqWithBody = new Request('/api/upload', {
method: 'POST',
body: JSON.stringify({fileId: 'abc123'})
});
// 第一次
fetch(reqWithBody);
// 第二次必须 clone
fetch(reqWithBody.clone());
用构造函数“克隆”时要小心覆盖和副作用
用 new Request(existingReq, init) 也能复制 Request,但它不是安全复用的首选方式:
- 会把源 Request 的 body 标记为
bodyUsed === true,哪怕你没读取过 - 如果 init 中有同名字段(如 method),会覆盖源值;但跨域时 referrer 会被清空,mode=navigate 会转成 same-origin
- 不推荐用于有 body 的复用场景
适合复用 Request 的典型场景
真正发挥 Request 复用价值的地方,往往不是简单发两次请求,而是需要精细控制流程:
- Service Worker 中缓存匹配:用 Request 对象做
cache.match(req),再转发给 fetch - 请求重试逻辑:失败后用同一 Request(或 clone)重新 fetch
- 多端适配:构造一个 Request,根据环境决定是直接 fetch 还是走代理或 mock
- 日志与监控:把 Request 实例传给埋点函数,统一记录 URL、method、headers


















