React-Native使用AWS-SDK上传图片至S3遇SignatureDoesNotMatch错误求助
React Native中AWS SDK上传S3图片签名不匹配问题解决
问题描述
在React-Native中使用AWS-SDK将图片上传至S3存储桶,访问权限与连接均正常,上传纯文本、列出存储桶及对象的操作都能成功执行,但上传图片时遇到签名不匹配错误。
上传代码
async function handleImage(capturedImage) { setImage(capturedImage); setScreenState(ScreenStates.LOADING); try { const result = await classifyImage(capturedImage); console.log(result.tensor_) // {dtype:"float32",shape:[…]} // dtype:"float32" // shape:[1,3,273,224] const blob_jpeg = new Blob([result.tensor_], {type: "image/jpeg"}); console.log(typeof blob_jpeg._data) // object console.log(blob_jpeg._data) // {blobId:"e7a667ad-4363-4a2e-9850-8695f103e9e0",offset:0,size:1489546,type:"image/jpeg",__collector:{}} try { const keyName = 'image.jpeg'; const putCommand = new PutObjectCommand({ Bucket: "mybucket", ContentType:"image/jpeg", Key: "myimage", Body: blob_jpeg._data, }); await s3.send(putCommand); console.log( 'Successfully uploaded data to ' + bucketName + '/' + keyName); } catch (e) { console.log(e,e); } }
错误信息
Error: "The request signature we calculated does not match the signature you provided. Check your key and signing method." in SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method. << at construct (native) << at apply (native) << at i (@aws-sdk/client-s3.js:3:461197)
解决方案
- 不要直接传递Blob的私有属性
_data,AWS SDK无法识别这个内部对象,应该直接使用Blob实例,或者将Blob转换为ArrayBuffer/Uint8Array后再作为Body参数。
示例代码:// 将Blob转为ArrayBuffer const arrayBuffer = await blob_jpeg.arrayBuffer(); const putCommand = new PutObjectCommand({ Bucket: "mybucket", ContentType:"image/jpeg", Key: "myimage", Body: arrayBuffer, }); - 核心问题:当前用模型输出的
tensor_直接包装成Blob是无效的,这不是正确的JPEG二进制数据。需要先将张量转换为标准的JPEG编码数据:
以TensorFlow.js为例,使用encodeJpeg方法将张量转为Uint8Array,再包装成Blob或直接上传:// 先将张量转为JPEG格式的Uint8Array const jpegUint8 = await tf.encodeJpeg(result.tensor_); // 直接上传Uint8Array const putCommand = new PutObjectCommand({ Bucket: "mybucket", ContentType:"image/jpeg", Key: "myimage", Body: jpegUint8, }); - 检查
PutObjectCommand中的Bucket和Key参数是否拼写正确,确保与其他成功操作的参数一致。 - 显式指定AWS SDK的签名版本为v4(React Native环境推荐):
const s3 = new S3Client({ region: '你的区域', credentials: { accessKeyId: '你的AccessKey', secretAccessKey: '你的SecretKey' }, signatureVersion: 'v4' });
内容的提问来源于stack exchange,提问作者Rayanaay
相关产品推荐
相关产品推荐

