response.body 是原生 readablestream,可直接用 for await...of 或 getreader() 流式读取 uint8array;仅能消费一次,与 .json() 等方法互斥,跨域需注意 cors 头限制。

在现代浏览器中,Response.body 本身就是原生的 ReadableStream 对象,无需额外转换。只要请求成功(状态码为 2xx),且响应体非空(如非 HEAD 请求、非 204/304 等无响应体的状态),response.body 就会是一个有效的 ReadableStream 实例。
确认 body 是 ReadableStream
可通过类型检查快速验证:
fetch('/api/data')
.then(response => {
console.log(response.body instanceof ReadableStream); // true
console.log(response.body); // 输出: ReadableStream { locked: false, ... }
});
直接使用 body 进行流式读取
可调用 getReader() 获取流读取器,逐块读取二进制数据:
- 使用
reader.read()返回 Promise,解析出{ done, value } -
value是Uint8Array,代表当前 chunk 的原始字节 - 记得调用
reader.releaseLock()或让 reader 被垃圾回收(推荐用for await...of自动管理)
示例(手动读取):
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log('Chunk:', value); // Uint8Array
}
reader.releaseLock();
更简洁的方式:用 for await...of 消费流
这是推荐做法,自动处理锁和迭代逻辑:
for await (const chunk of response.body) {
console.log(chunk); // 每个 chunk 都是 Uint8Array
}
注意:response.body 只能被消费一次。一旦读取完毕或中断(如抛错未处理),流即关闭,再次遍历会报错“Cannot read from a locked stream”。
常见注意事项
-
CORS 限制:跨域响应若未携带
Access-Control-Expose-Headers: Content-Length等头,部分属性(如bodyUsed)可能受限,但body本身仍可用 -
避免与 .json()/.text() 混用:调用
response.json()后,response.body已被锁定,不能再读取 -
流不可重用:若需多次使用,可先用
response.clone()创建副本,再分别读取











