你以为 fetch 的 response.body 只能靠 TextDecoderStream 绕一行?今天 Chrome 把这件事彻底原生化了

每次用 fetch 拿数据,你大概都写过这套样板:

const response = await fetch(url);
const stream = response.body.pipeThrough(new TextDecoderStream());

三行。好用。但每次都要 pipeThrough(new TextDecoderStream()) 这一步——很多人第一次写的时候还容易忘,然后流出来的全是乱码。

这就是 textStream() 要解决的问题。

Chrome 158(预计 2026 年秋季稳定版)给 Response、Request、Blob 三个接口加了一个 textStream() 方法,直接返回 UTF-8 解码后的文本流。上面三行变成一行:

const stream = response.textStream();

就这么简单。

textStream() 从哪来的

这个 API 不是 Chrome 自己拍脑袋的。WHATWG fetch 规范里有一个 Body mixin,Request 和 Response 都继承自它。2025 年 10 月,Chromium 工程师 Philip Jägenstedt(foolip)和 Noam Rosenthal 向 WHATWG fetch 提交了一个 PR,在 Body mixin 上加 textStream() 方法,核心动机就是减少样板代码和避免「忘了 pipeThrough TextDecoderStream」这个常见坑。

规范在 2026 年 5 月合并进 fetch 标准。Chromium 在 2026 年 5 月实现了 behind a flag 的版本(Chromium commit 7864305),Firefox 在 2026 年 6 月跟进了实现(mozilla-firefox commit e0757fc),Safari 目前没有官方表态但 MDN 上已经有实验性支持标注。

所以这是一个真正的跨浏览器标准,不是 Chrome 专属。

你会怎么用它

场景一:逐块读取服务端发送的日志

const response = await fetch("/api/live-logs");
const reader = response.textStream().getReader();

while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  console.log("收到日志块:", value);
}

没有 pipeThrough,没有 TextDecoderStream,直接拿到文本块。

场景二:流式读取 AI 响应

const response = await fetch("/api/chat", {
  method: "POST",
  body: JSON.stringify({ message: "讲讲 Rust 前端工具链" }),
  headers: { "Content-Type": "application/json" }
});

for await (const chunk of response.textStream()) {
  appendToChat(chunk);
}

场景三:读取大文件内容

const fileBlob = await fetch("/large-file.txt").then(r => r.blob());
const textStream = fileBlob.textStream();

它不是什么

textStream() 只返回 UTF-8 解码后的文本流。如果你需要其他编码,用 response.body + TextDecoderStream 自己指定 encoding:

const stream = response.body.pipeThrough(new TextDecoderStream("gbk"));

textStream() 也不做整体的 text()——它返回的是流,不是 Promise<string>。要拿整个 body 当字符串,还是得 response.text()。

浏览器支持现状

Chrome 151+ 已经把 textStream() 标记为 Experimental Full Support。Firefox 暂未正式支持,Safari 无标注。如果你现在要用,生产环境建议做个特性检测:

const getTextStream = (response) => {
  if (typeof response.textStream === "function") {
    return response.textStream();
  }
  return response.body.pipeThrough(new TextDecoderStream());
};

三步下一步

  1. 现在就在 Chrome 151+ 里试:开 Chrome 158 canary,加到 SPA 里跑一下 fetch 流式文本
  2. 给团队写一个封装函数:特性检测 + 类型标注,统一走 textStream(),旧的 pipeThrough 代码逐步替换
  3. 跟进 Firefox 支持:跟踪 Mozilla 的 platform-status 页面,等 Firefox 稳定版支持后去掉 @supports 检测

这个 API 很小,但很实用。fetch 的 body 流处理样板减掉两步,开发者犯错的机会就少一个。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 702 阅读