如何使用Fetch API将照片上传到AWS S3



我正在尝试使用Fetch API将照片文件上传到S3存储桶。当我试图上传照片时,在POST上收到了400个错误请求。我正确地获得了预签名的帖子url和文件详细信息,但我认为我格式化表单数据的方式是不正确的。

我使用的是一个html文件输入,它使用onchange来运行javascript函数handlePhoto。

html是

<input type="file" onchange="handlePhoto()" id="file_input"/>

javascript函数是

function handlePhoto(){
const file = document.getElementById('file_input').files[0]
let formData = new FormData()
fetch("/v1/photos/get_presigned_post/" , {
method: "GET"
})
.then(response => response.json())
.then(s3Result => {
const { url, fields } = s3Result;
Object.keys(s3Result.fields).forEach(key => {
formData.append(key, s3Result.fields[key]);
});
formData.append('acl', 'public-read');
formData.append('Content-Type', file.type);
formData.append("file", file);
fetch(url, {
method: "POST",
body: formData,
headers: {
"Content-Type": "multipart/form-data"
}
})
});
}

如有任何帮助,我们将不胜感激。

假设你有一个预先签名的url,你可以使用这样的东西:

interface UploadToS3Params {
url: string;
file: File;
}
export function uploadToS3(params: UploadToS3Params) {
const { file, url } = params;
return fetch(url, {
body: file,
mode: "cors",
method: "PUT",
// optional headers
// headers: { "Content-Type": "text/plain" },
});
}

检查s3Result中的url,对我来说,它是错误的链接,并且不包括我的bucketname。url必须是这样才能工作:

https://{bucket_name}.s3.amazonaws.com

您的URL可能不对,从文档中看,主机名应该是这样的。"s3.地区.amazonaws.com";。

这两个链接可能会有所帮助https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAPI.html和https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTForms.html

您不需要使用FormData,只需传递内容类型为"octet-stream"的文件即可。

生成预签名URL时必须使用acl。

fetch(url, {
method: 'PUT',
body: file,
headers: { 'Content-Type': 'application/octet-stream' }
})

最新更新