使用Node.js+LocalStack上传图片至S3时遇XML解析错误求助
本地使用LocalStack模拟S3服务,通过Node.js编写API上传图片时触发以下错误:
exception during call chain: Unable to parse request (not well-formed (invalid token): line 1, column 0), invalid XML received:
API代码如下:
const s3 = new AWS.S3({ accessKeyId: 'testKEYId', secretAccessKey: 'testSecret', region: 'ap-south-1', sslEnabled: false, endpoint: 'http://localhost:4566', }); app.post('/upload-1', upload.any(), (req, res) => { const imagePath = './myfolder/my-image.jpg'; // Update with your image file path const bucketName = 'my-buckert'; // Update with your S3 bucket name const remoteFileName = 'uploaded_image.jpg'; const fileContent = fs.readFileSync(imagePath); console.log(fileContent); const params = { Bucket: bucketName, Key: remoteFileName, Body: fileContent, }; const bucketParams = { Bucket: bucketName, } s3.upload(params, (err, data) => { if (err) { console.error('Error uploading image to S3:', err); } else { console.log('Image uploaded successfully. S3 location:', data.Location); } }); });
修正存储桶名称
S3(含LocalStack)对桶名有严格规则:仅允许小写字母、数字、连字符,不能以连字符开头/结尾,也不能有连续连字符。你代码中的桶名my-buckert虽然拼写错误,但主要确认是否符合规则,建议直接改为my-bucket测试。提前创建目标存储桶
LocalStack不会自动创建不存在的桶,你代码中定义了bucketParams但未执行创建操作。可以在上传逻辑前添加创建桶的代码:s3.createBucket(bucketParams, (err) => { if (err) console.error('Bucket creation failed:', err); // 桶创建完成后再执行上传 s3.upload(params, (uploadErr, data) => { // 上传回调逻辑 }); });或者用LocalStack CLI手动创建:
awslocal s3 mb s3://my-bucket开启路径风格访问配置
新版AWS SDK默认使用虚拟主机风格访问S3,而LocalStack默认适配路径风格,这会导致请求解析异常。修改S3客户端配置,添加s3ForcePathStyle: true:const s3 = new AWS.S3({ accessKeyId: 'testKEYId', secretAccessKey: 'testSecret', region: 'ap-south-1', sslEnabled: false, endpoint: 'http://localhost:4566', s3ForcePathStyle: true // 新增该配置项 });验证文件读取有效性
检查./myfolder/my-image.jpg的路径是否正确(相对路径以Node.js进程启动目录为基准),可以添加读取异常捕获:let fileContent; try { fileContent = fs.readFileSync(imagePath); } catch (readErr) { console.error('File read failed:', readErr); return res.status(500).send('File not found'); }更新LocalStack版本
旧版本LocalStack存在S3请求解析的已知bug,建议升级到最新稳定版:pip install --upgrade localstack,之后重启LocalStack服务。
内容的提问来源于stack exchange,提问作者Abhishek Rawal

