Cypress拦截gzip压缩Mapbox请求的Mock方案咨询
Cypress 离线Mock Mapbox GL pbf资源的落地方案
现有拦截代码的显性问题
你之前的写法有几个必错的配置,先修正再谈绕开Bug:
- 状态码错误使用了204 No Content,该状态码语义为响应无返回体,无论配置什么fixture内容,浏览器都会直接丢弃响应体,pbf资源必然加载失败,返回静态资源必须使用
200 OK - 手动配置了和实际返回体不匹配的
Transfer-Encoding: chunked、content-encoding: compress头:如果直接返回原始未压缩pbf文件,这类头会导致客户端解析响应体失败,Cypress会自动处理传输层编码,不需要手动配置 - fixture的二进制引用写法过时:旧版本
,binary后缀的写法在新版Cypress中存在兼容问题,会导致文件读取时编码错乱。
绕开Cypress #16420 二进制拦截Bug的可行方案
该Issue的核心原因是Cypress代理层会强制将二进制响应按UTF-8字符串转码,导致pbf这类二进制文件内容损坏,以下方案均可以完全绕开这个缺陷:
方案1:Service Worker层拦截(最稳定,零依赖)
完全跳过Cypress的请求代理层,利用浏览器原生Service Worker做请求替换,不会触发转码问题:
- 提前把所有需要Mock的pbf字体、瓦片文件存到项目测试静态资源目录
- 编写极简Service Worker脚本,匹配所有Mapbox pbf资源路径,命中后直接返回本地预存的pbf文件响应,仅配置
content-type: application/x-protobuf和access-control-allow-origin: *两个必要响应头 - 在测试的
before钩子中,通过cy.visit的onBeforeLoad回调提前注册该Service Worker,等SW激活后再初始化Mapbox实例即可。
方案2:本地静态代理层替换
完全把Mock逻辑放到Cypress之外的本地服务,Cypress仅做页面流程控制,不触碰响应内容:
- 测试启动前用Express等工具起一个本地代理服务,所有匹配Mapbox pbf路径的请求,直接通过
res.sendFile返回磁盘上的原始pbf文件,其余请求按测试需求转发或返回Mock内容 - Cypress配置走该本地代理访问测试页面,这种模式下Cypress不会篡改二进制响应体,和真实网络请求的表现完全一致。
方案3:适配新版Cypress的intercept写法(适合轻量场景,有偶发失败概率)
如果一定要用cy.intercept,按如下写法规避已知问题,不要用静态fixture配置,改用回调手动返回二进制内容:
// 首先在cypress.config.js中配置pbf文件的二进制解析规则 // e2e: { // setupNodeEvents(on) { // on('file:preprocessor', (file) => { // if (file.outputPath.endsWith('.pbf')) { // return require('cypress/lib/util/return-binary-body')(file.filePath) // } // }) // } // } cy.intercept( { method: 'GET', url: /fonts\/v1\/mapbox\/.*\.pbf/ }, (req) => { req.reply({ statusCode: 200, body: Cypress.Blob.createBlobFromData( Cypress.fixture('fonts/italic.arial.0-255.pbf', 'binary') ), headers: { 'content-type': 'application/x-protobuf', 'access-control-allow-origin': '*' } // 不要加任何其他冗余响应头,尤其是content-encoding、transfer-encoding相关 }) } ).as('getMapboxFontPbf')
- 注意不要对预存的pbf文件做任何gzip/br/compress预压缩,直接保存从Mapbox抓下来的原始未压缩文件即可,手动配置压缩头但返回体不匹配会直接导致解析失败。
通用避坑清单
- 所有pbf资源返回必须使用200状态码,离线场景下不要用304、204这类无实体/协商缓存的状态码
- 不要手动配置
content-encoding响应头,除非你能保证返回体是对应编码压缩后的完整内容 - 旧版fixture路径后加
,binary的写法已经废弃,不要再用 - Mapbox初始化时可以把
maxParallelImageRequests调小到4-6,避免并发请求过高触发Cypress代理队列异常。
内容的提问来源于stack exchange,提问作者relief.melone
相关产品推荐
相关产品推荐

