当前位置: 首页 > news >正文

msw 中每个接口的 request 是不是只能await 一次?

MSW(Mock Service Worker) 中,每个 request 对象本身并不是只能 await 一次,但你提到的疑问很可能源于对 Response 返回方式流式响应(streaming) 的误解。下面详细解释:


✅ 核心结论

MSW 的 req(Request)对象可以被多次读取或检查(如 req.url, req.method),但 req.body(请求体)作为可读流(ReadableStream),在浏览器中默认只能消费一次。

这其实是 Fetch API 的标准行为不是 MSW 特有的限制


🔍 详细说明

1. Request.body 是一个 ReadableStream

// 在 MSW handler 中
rest.post('/api/login', async (req, res, ctx) => {// ❌ 第一次 await req.json() 消费了 body 流const body1 = await req.json();// ❌ 第二次 await req.json() 会报错!// TypeError: Already readconst body2 = await req.json(); // 💥 报错!return res(ctx.json({ ok: true }));
});

这是因为:

  • req 是一个标准的 Request 对象。
  • req.json()req.text()req.formData() 等方法会 读取并关闭底层的 body
  • 流一旦被消费(consumed),就不能再次读取。

⚠️ 这是 浏览器 Fetch API 的设计,Node.js 环境下(如 Vitest + MSW)也模拟了这一行为。


2. 如何“多次使用”请求体?

正确做法:只 await 一次,然后复用变量

rest.post('/api/login', async (req, res, ctx) => {const payload = await req.json(); // ✅ 只读一次console.log('Payload:', payload);if (payload.username === 'admin') {return res(ctx.json({ role: 'admin' }));}return res(ctx.json({ role: 'user' }));
});

如果需要在多个地方处理,提前解析并传参


3. 特殊情况:克隆 Request(不推荐用于 body)

你可以用 req.clone() 克隆整个请求:

const req1 = req.clone();
const req2 = req.clone();const data1 = await req1.json();
const data2 = await req2.json(); // ✅ 可以!

MSW 官方不建议这样做,因为:

  • 增加内存开销
  • 大多数场景没必要
  • 如果 body 很大(如文件上传),可能影响性能

📌 最佳实践:解析一次,到处使用。


🧪 验证示例(会报错)

// ❌ 错误示范
rest.post('/test', async (req, res, ctx) => {console.log(await req.text()); // OKconsole.log(await req.text()); // Uncaught TypeError: Failed to execute 'text' on 'Body': body stream already read
});

📝 总结

问题 答案
MSW 中每个接口的 req 能否多次 await req.json() 不能,因为 req.body 是单次消费的流
这是 MSW 的 bug 吗? 不是,是 Fetch API 标准行为
如何解决? 只解析一次,存到变量中复用
能用 req.clone() 吗? ✅ 技术上可以,但不推荐

如果你正在写 MSW handler 并遇到 “Already read” 错误,检查是否不小心多次调用了 req.json() / req.text() 即可。

http://www.jsqmd.com/news/309518/

相关文章:

  • 完整教程:《山东省人工智能终端创新发展行动方案》解析
  • YOLO26优化:block优化 | 简单高效的模块-现代反向残差移动模块 (iRMB) | ICCV2023 EMO
  • YOLO26优化:注意力魔改 | 多尺度空洞注意力(MSDA),有效捕捉多尺度信息 | 中科院一区顶刊
  • SpringMVC大文件上传后如何加密存储?
  • 新版本Cesium离线部署方法
  • 2026衬塑涂塑钢管厂家综合评测(附优选名单)|采购避坑,适配多行业
  • 【超全】基于微信小程序的微信阅读平台【包括源码+文档+调试】
  • Java Web 系统开发流程与三层架构设计实践(Spring Boot + MySQL)
  • 本地部署文档管理平台 BookStack 并实现外部访问( Windows 版本)
  • 【超全】基于微信小程序的高校考试模拟系统【包括源码+文档+调试】
  • 强烈安利!MBA必备TOP10 AI论文网站测评
  • 什么是VIP专车道
  • 开发闲鱼卖货标题优化工具,输入商品名称,自动生成三组高爆光标题,(含热搜索关键词,商品卖点),适配闲鱼搜索规则,提升商品浏览量。
  • GraphQL注入攻击模式:解剖现代API的注入风险
  • 2026年商店场景咖啡机器人选购指南
  • Maven + MyBatis 进阶实战:Emp 表动态 SQL 全场景实现(附完整代码)
  • 案例:一次完整的SSO系统渗透测试
  • 【图像分割】【由局部高斯分布拟合能量驱动的活动轮廓】基于区域的主动轮廓模型,采用变分水平集形式用于图像分割附Matlab代码
  • OA系统开发中,UEDITOR的ELECTRON插件如何实现WORD截图转存?
  • 【图像融合】基于联合双边滤波和局部梯度能量的多模态医学图像融合研究附Matlab代码
  • 【图像增强】使用多融合技术进行水下图像增强研究附Matlab代码
  • 蛋白质磷酸化修饰类别、富集和鉴定方法
  • 【完美复现】在具有灵活结构的孤岛式直流微电网中的分层控制【IEEE16节点】附Matlab代码
  • 【同步挤压变换和重新分配方法】【时频分析(TFA)】解决海森堡不确定性原理(HUP)提供新的方法附Matlab代码
  • 【图像处理】边缘检测(Roberts、Prewitt、Sobel、Marr-Hildreth 和 Canny 边缘检测器)和图像分割(Otsu 方法)附matlab代码
  • 【图像处理】基于离散余弦变换和小波变换的图像压缩附Matlab代码
  • 【图像处理】使用逆滤波器和维纳滤波器进行图像恢复附Matlab代码
  • langchian团队最新框架 deepagent
  • 【图像处理】水下图像增强的颜色平衡与融合技术研究附Matlab代码
  • 一些网络流的基础模型