Cypress拦截二进制Zip下载接口导致文件损坏问题排查
问题描述
- 需求:使用Cypress拦截二进制Zip文件的下载API请求,并用本地文件模拟响应。后端返回
application/octet-stream类型的二进制数据。 - 异常情况:真实环境中Blob大小为31478,可正常解压;但Cypress模拟后Blob大小变为56721,解压时提示
Error: Corrupted zip: missing 2059592310 bytes。 - 已尝试操作:
- 移除
accept-encoding请求头 - 用
utf-8/binary编码读取本地文件 - 设置
Accept-Ranges和Content-Length响应头
- 移除
- 更新发现:用
binary编码读取文件后,写入本地可正常解压,但API返回的Blob大小仍异常;设置Content-Length后Blob大小正确,但Zip仍损坏。
原测试代码:
Then('I navigate to the live settings tab and intercept the download call', () => { cy.readFile('src/fixtures/machines/machine-settings-export/settings_values.zip', 'utf-8').then((file) => { cy.intercept('GET', '**/backup', (req) => { req.headers['accept-encoding'] = null; console.warn('headers', req.headers); console.warn('file', file); req.reply({ statusCode: 200, body: file, headers: { 'Content-Type': 'octet-stream', }, }); }).as('downloadCall'); cy.get('machine-configurations-dialog').contains('LIVE MASCHINEN-EINSTELLUNGEN').click(); }); cy.wait('@downloadCall') .its('request') .then((req) => { console.warn('download intercept its request: ', req); const fileName = `1234TEST.zip`; saveAs(req.body, fileName); }); });
解决方案
问题核心是二进制文件读取和响应体处理的编码错误,修改后的代码如下:
Then('I navigate to the live settings tab and intercept the download call', () => { // 用null编码读取原始二进制Buffer,避免编码转换损坏文件 cy.readFile('src/fixtures/machines/machine-settings-export/settings_values.zip', null).then((fileBuffer) => { cy.intercept('GET', '**/backup', (req) => { // 删除压缩请求头,防止Cypress自动处理编码 delete req.headers['accept-encoding']; req.reply({ statusCode: 200, body: fileBuffer, // 直接返回原始Buffer headers: { 'Content-Type': 'application/octet-stream', 'Content-Length': fileBuffer.length.toString(), // 设置真实文件长度 'Content-Disposition': 'attachment; filename="settings_values.zip"' // 可选:指定下载文件名 }, }); }).as('downloadCall'); cy.get('machine-configurations-dialog').contains('LIVE MASCHINEN-EINSTELLUNGEN').click(); }); cy.wait('@downloadCall') .its('response.body') // 读取响应体而非请求体 .then((responseBuffer) => { const fileName = `1234TEST.zip`; // 将Buffer转为Blob后保存 const blob = new Blob([responseBuffer], { type: 'application/octet-stream' }); saveAs(blob, fileName); }); });
关键说明
- 用
null编码读取文件:指定null时,cy.readFile返回原始Buffer对象,不会进行任何字符编码转换,彻底避免二进制数据损坏。 - 响应体直接传Buffer:Cypress会自动将Buffer处理为正确的二进制响应,无需手动转换格式。
- 设置真实
Content-Length:通过Buffer的length属性设置响应头,确保前端收到的Blob大小与真实文件一致。 - 读取
response.body:原代码错误读取了请求体,实际下载的是API返回的响应体数据。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

