如何让运行在Node+jsdom测试环境下的Mock Service Worker接收跨域Cookie?
问题根因
- 跨域请求默认不携带Cookie:浏览器(含JSDOM环境)的同源策略要求,跨域请求必须显式配置
credentials: 'include'才会携带对应目标域的Cookie,否则请求默认不带Cookie。 - MSW拦截逻辑默认未适配跨域Cookie传递:MSW接管全局
fetch/XMLHttpRequest后,默认不会主动从JSDOM的Cookie存储中匹配目标域的Cookie,同时如果未配置正确的CORS响应头,JSDOM也会阻止Cookie的传递。 - 未配置请求透传:MSW启动后默认拦截所有出站请求,如果你要向真实Express服务发请求,没有配置透传规则的话,请求会被MSW拦截,自然不会发送到真实Express服务,也就不会收到Cookie。
解决方案
1. 所有跨域请求显式添加credentials配置
发送跨域fetch请求时,必须添加credentials: 'include'参数:
// 示例配置 fetch('http://localhost:4444', { credentials: 'include' })
2. 配置MSW的CORS响应头
在MSW的请求处理函数中,添加对应的CORS响应头,允许跨域携带Cookie:
import { rest } from 'msw' export const handlers = [ rest.get('http://localhost:4444', (req, res, ctx) => { return res( // 配置允许的源,不能用*,必须和JSDOM运行的源完全匹配 ctx.set('Access-Control-Allow-Origin', 'http://localhost'), // 允许携带Cookie ctx.set('Access-Control-Allow-Credentials', 'true'), ctx.json({ status: 'success' }) ) }) ]
3. 配置MSW透传真实服务请求
如果需要同时使用MSW和真实Express服务,启动MSW时配置透传规则,让发往Express服务的请求绕过MSW拦截直接走真实网络:
beforeAll(() => server.listen({ // 将你需要访问的真实Express服务域名加入透传列表 passThrough: ['http://localhost:5555'] }))
4. 版本兼容校验
如果使用的是MSW 1.x版本,建议升级到MSW 2.x及以上版本,旧版本存在跨域Cookie处理的已知缺陷,升级后可直接解决大部分适配问题。
内容的提问来源于stack exchange,提问作者aryzing
相关产品推荐
相关产品推荐

