从Gitlab REST端点下载仓库Zip文件并上传至S3后文件损坏的技术求助
解决GitLab Zip文件下载后上传S3损坏的问题
你遇到的问题核心原因很明确:Axios默认会把响应解析成UTF-8字符串,而GitLab返回的是二进制格式的Zip文件,字符串编码转换会直接破坏文件的二进制结构,导致上传到S3后文件损坏。Postman能正常保存是因为它直接处理原始二进制响应,没有做多余的编码转换。
具体修复步骤
指定Axios响应类型为二进制
在Axios请求配置里添加responseType: 'arraybuffer',让Axios保留原始的二进制数据,避免转换成字符串。修正S3参数的语法细节
- 确保上传的
Body是正确的二进制数据 - 修复
ResponseContentDisposition的引号不匹配问题(你的原代码里有语法错误)
- 确保上传的
修正后的完整代码
const requestURL = `https://gitlab.com/api/v4/projects/${repoID}/repository/archive.zip?sha=${commitSHA}`; let url = await Axios({ method: "GET", url: requestURL, headers: { Accept: "*/*", Authorization: "Bearer " + authToken, }, responseType: 'arraybuffer' // 关键配置:保留二进制响应 }) .then(async (res) => { const Key = "path/to/test.zip"; const params = { Bucket: BUCKET_URL, Key, Body: res.data, // 此时res.data是ArrayBuffer格式的二进制数据 ContentType: "application/zip", }; await s3.upload(params).promise(); const signedURL = await s3.getSignedUrl("getObject", { Bucket: BUCKET_URL, Key, ResponseContentDisposition: 'attachment; filename="test.zip"' // 修正引号匹配 }); return signedURL ; }) .catch((error) => { console.error("请求或上传出错:", error); throw error; // 建议抛出错误,便于调用方捕获处理 }); return url;
针对大文件的优化方案
如果你的Zip文件体积较大,推荐使用responseType: 'stream',直接将响应流传递给S3,这样能减少内存占用,更适合无服务器函数的运行环境:
const response = await Axios({ method: "GET", url: requestURL, headers: { Accept: "*/*", Authorization: "Bearer " + authToken, }, responseType: 'stream' // 使用流处理大文件 }); const params = { Bucket: BUCKET_URL, Key: "path/to/test.zip", Body: response.data, // 直接传递响应流 ContentType: "application/zip" }; await s3.upload(params).promise();
这样修改后,S3中存储的Zip文件就能正常打开,前端通过预签名URL下载的文件也不会再损坏。
内容的提问来源于stack exchange,提问作者malikite
相关产品推荐
相关产品推荐

