You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Node.js通过预签名URL上传.tar.gz至S3失败问题排查

问题分析与解决方案

核心问题点

  1. Content-Length计算错误:
    你用new Blob([data]).size计算内容长度,但在Node.js环境中,fs.readFileSync返回的是Buffer,直接用data.length就能得到正确的字节数。用Blob计算可能导致长度不匹配,S3会因为内容实际长度与请求头声明的不一致,静默拒绝上传(无错误提示但不完成上传)。

  2. Content-Encoding头设置错误:
    .tar.gz是已经经过gzip压缩的文件,你设置Content-Encoding: gzip会让S3认为你上传的是未压缩内容经过gzip编码传输,S3会自动尝试解压内容后存储。这与你要上传压缩文件本身的需求冲突,导致上传流程异常中断。

修正后的代码

const tarFile = '/tmp/some.tar.gz';
const data = fs.readFileSync(tarFile);

const req = https.request(
  url,
  {
    method: 'PUT',
    headers: {
      'Content-Length': data.length, // 直接用Buffer的length获取正确字节数
      'Content-Type': 'application/x-gzip', // 仅保留文件类型头
      // 移除Content-Encoding: gzip
    },
  },
  (res) => {
    let responseBody = '';
    res.on('data', (chunk) => {
      responseBody += chunk;
    });
    res.on('end', () => {
      console.log({ responseBody, statusCode: res.statusCode }); // 额外打印状态码便于排查
    });
  }
);
req.on('error', (err) => {
  console.error('上传错误:', err);
  reject(err);
});
req.write(data);
req.end();

额外排查建议

  • 打印响应的statusCode:通过res.statusCode可以获取S3返回的状态码,比如400(请求错误)、403(权限问题)等,帮助快速定位问题。
  • 检查预签名URL的有效期和权限:确保预签名URL未过期,且包含PUT操作的权限。
  • 验证文件完整性:确认/tmp/some.tar.gz文件本身无损坏,可以本地解压测试。

内容的提问来源于stack exchange,提问作者gagan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 09:12:11