使用Axios向Heroku的put_url发起PUT请求时遇签名不匹配错误
Axios上传Heroku Source文件时出现SignatureDoesNotMatch错误的解决办法
成功获取Heroku的put_url后,Postman和原生Node.js https.request都能正常完成文件上传,但用Axios实现时却触发SignatureDoesNotMatch错误,提示请求签名不匹配。
问题根源
对比两段代码,核心差异出在文件读取方式和请求配置上:
- 原生代码中
fs.readFileSync未指定编码,返回的是原始二进制Buffer,完全符合签名验证的字节流要求; - Axios代码中用
utf-8编码读取二进制压缩文件,直接破坏了原始字节结构,导致服务器计算的签名和请求携带的签名不匹配; - 手动设置的
Content-Type(text/plain)和Content-Length也不符合二进制文件的上传规则。
修正后的Axios代码
const data = fs.readFileSync(zipPath); // 不指定编码,直接获取原始二进制Buffer const config = { method: 'put', url: put_url, headers: { 'Accept-Encoding': 'gzip, deflate, br', // 可选:手动指定二进制文件的Content-Type,或直接让Axios自动处理 // 'Content-Type': 'application/octet-stream', }, data, // 禁止Axios自动转换请求数据,确保Buffer直接发送 transformRequest: [(data) => data], }; await axios(config);
关键修改说明
- 读取原始二进制数据:去掉
utf-8编码参数,让fs.readFileSync返回Buffer,保证上传的字节流和原始文件完全一致,这是解决签名问题的核心; - 修正Content-Type:二进制文件推荐使用
application/octet-stream,或直接省略让Axios自动识别,避免text/plain导致服务器错误解析; - 关闭数据转换:Axios默认会将非FormData数据转为JSON,添加
transformRequest配置确保二进制Buffer不被修改; - 移除手动Content-Length:Axios会自动根据
Buffer长度计算并设置该请求头,手动设置反而可能因为编码偏差导致长度错误。
修改后重新测试,即可和原生https.request一样正常完成文件上传。
内容的提问来源于stack exchange,提问作者ETFairfax
相关产品推荐
相关产品推荐

