Node.js对接Amazon S3分片上传时SHA256计算结果不匹配问题求助
问题根因
你代码里有4个核心错误直接导致哈希校验不通过:
- 读文件流时错误指定了
encoding: "base64":这个配置会让fs.createReadStream返回base64编码的字符串,而不是原始二进制Buffer。你基于base64字符串计算的SHA256,和S3端基于二进制分片计算的结果必然不一致。 - axios请求体格式错误:你把分片套在
{body: 分片内容}的对象里,axios默认会将这个对象序列化为JSON格式传输,S3收到的是JSON字符串而非原始分片内容,校验自然失败。 - 哈希计算逻辑隐含编码问题:
crypto.createHash().update()方法如果接收字符串类型的输入,会默认用UTF-8编码转成二进制再计算哈希,你传入base64字符串时不会自动解码为原始二进制,进一步放大了哈希计算的偏差。 - 细节错误:一是提前定义的变量是
file_id,但axios请求路径里用的是fileId,变量不一致会导致请求路径错误;二是axios的请求头配置字段应该是headers(复数),你写成了单数header会导致自定义请求头不生效。
修复方案
按以下步骤修改代码即可解决问题:
- 移除
fs.createReadStream的encoding配置,让流直接返回原始二进制Buffer - 调整axios请求参数,直接将Buffer作为请求体,避免axios自动序列化内容
- 修正变量名、请求头字段名的拼写错误
修复后核心代码示例
const crypto = require('crypto'); const fs = require('fs'); const axios = require('axios'); // 输入为原始二进制Buffer,直接计算对应SHA256的base64结果 const Encryptsha256 = function(chunksTobeHashed) { return crypto.createHash('sha256').update(chunksTobeHashed).digest('base64'); } const upload = async function(uploadFile) { const folderPath = uploadFile.filePath; const chunksArray = []; // 去掉encoding配置,默认返回二进制Buffer const uploadFileStream = fs.createReadStream(folderPath, { highWaterMark: 1 * 1024 * 1024 }); uploadFileStream.on('data', (chunk) => { chunksArray.push(chunk); }); uploadFileStream.on('error', (error) => { console.log('读取文件失败: ', error); }); uploadFileStream.on('end', async() => { const file_id = "2fe44d18-fa94b201-2fe44d18b196-f9066e05a81c"; const promises = []; for (let i = 0; i < chunksArray.length; i++) { const chunk = chunksArray[i]; const Content_SHA256 = Encryptsha256(chunk); // 直接把Buffer作为请求体,不要套额外对象 promises.push( axios.post( // 修正变量名,使用正确的file_id `${baseURL}/home/url/upload/${file_id}/chunk/${i}`, chunk, { // 修正为复数形式headers headers: { 'Content-SHA256': Content_SHA256, // 声明请求体为二进制流,避免axios自动转格式 'Content-Type': 'application/octet-stream' }, } ) ); } try { const response = await Promise.all(promises); console.log('所有分片上传成功: ', response); } catch (error) { console.log('分片上传失败: ', error); } }); }
内容的提问来源于stack exchange,提问作者m-0-h
相关产品推荐
相关产品推荐

