如何将Node.js的fs createReadStream转为适配原生fetch的Web流?
在Node.js v18+中将Node原生流转换为Web流用于原生fetch
Node.js v18及以上版本提供了原生API实现Node流与Web流的双向转换,无需额外依赖。针对你的上传场景,只需使用核心stream模块的Readable.toWeb()方法,就能把fs.createReadStream()返回的Node原生可读流转成原生fetch支持的Web ReadableStream。
基础实现示例
import { createReadStream } from 'fs'; import { Readable } from 'stream'; // 创建Node原生可读流 const nodeFileStream = createReadStream('./your-file.ext'); // 转换为Web标准的ReadableStream const webStream = Readable.toWeb(nodeFileStream); // 用原生fetch上传文件 const uploadResponse = await fetch('https://your-upload-endpoint.com', { method: 'POST', body: webStream, headers: { // 根据文件实际类型设置对应的Content-Type 'Content-Type': 'application/octet-stream' } }); const uploadResult = await uploadResponse.json(); console.log('上传结果:', uploadResult);
优化:添加Content-Length请求头
为了让服务器更高效处理上传请求,建议提前获取文件大小并设置Content-Length头:
import { createReadStream, stat } from 'fs/promises'; import { Readable } from 'stream'; // 获取文件元信息,拿到文件大小 const fileStats = await stat('./your-file.ext'); // 创建Node原生流 const nodeFileStream = createReadStream('./your-file.ext'); // 转换为Web流 const webStream = Readable.toWeb(nodeFileStream); const uploadResponse = await fetch('https://your-upload-endpoint.com', { method: 'POST', body: webStream, headers: { 'Content-Type': 'application/octet-stream', 'Content-Length': fileStats.size.toString() } });
关键说明
- Node.js的
Readable流(包括fs.createReadStream返回的实例)从v17.0.0开始内置toWeb()方法,v18作为LTS版本完全支持该特性。 - 原生fetch遵循Web标准,仅接受Web
ReadableStream作为body参数,这是直接传入Node流会报错的核心原因,转换后即可解决兼容性问题。 - 若需反向转换(Web流转Node流),可使用
Readable.fromWeb()方法。
内容的提问来源于stack exchange,提问作者Akxe
相关产品推荐
相关产品推荐

