用Node.js读取图片上传AWS S3后下载文件损坏该如何解决
你的代码错误原因是将base64编码后的字符串直接作为上传内容传递给S3,S3会将该字符串直接存储为文件内容,而非解码后的原始图片二进制数据,因此下载后的文件实际是base64文本,无法被识别为图片。
具体根因
- 调用
fs.readFileSync时指定了encoding: 'base64'参数,此时返回值是base64编码的字符串,而非图片原始的二进制Buffer - AWS S3的
ManagedUpload接收字符串类型的Body参数时,会默认以文本形式存储,不会自动对base64内容做解码操作,最终存储的文件和原始图片二进制不一致
修复方案
方案1:直接读取二进制Buffer(推荐)
去掉readFileSync的encoding参数,直接读取文件的二进制Buffer传递给S3即可。如果需要让S3正确识别文件类型,避免浏览器访问时自动下载,可额外新增ContentType配置:
var fs = require('fs'); var AWS = require('aws-sdk'); AWS.config.update({region: 'us-east-1'}); const BUCKET_NAME = 'my-bucket-name'; let filepath = '/home/user/test-image.jpeg'; // 去掉encoding配置,直接返回二进制Buffer const content = fs.readFileSync(filepath); let params = { params: { Bucket: BUCKET_NAME, Key: 'test.jpeg', Body: content, ContentType: 'image/jpeg' // 可选:配置文件MIME类型 } }; var upload = new AWS.S3.ManagedUpload(params); var promise = upload.promise(); promise.then( function(data) { console.log("Successfully uploaded photo."); }, function(err) { console.error("There was an error uploading: ", err.message); } );
方案2:保留base64读取逻辑,手动转Buffer
如果业务确实需要先读取为base64字符串,传递给S3前需手动转成二进制Buffer:
// 原有base64读取逻辑不变 const content = fs.readFileSync(filepath, {encoding: 'base64'}); let params = { params: { Bucket: BUCKET_NAME, Key: 'test.jpeg', Body: Buffer.from(content, 'base64'), // 把base64转成Buffer再上传 ContentType: 'image/jpeg' } };
内容的提问来源于stack exchange,提问作者alphanumeric
相关产品推荐
相关产品推荐

