使用 fetch api 使用预签名 url amazon s3 上传图像

fre*_*hme 7 amazon-s3 elixir reactjs

您好,我正在尝试客户直接在 ReactJS Web 应用程序中将他们的图片上传到亚马逊 s3。我在后端生成预签名网址,如下所示

def get_presigned_url(file_extension, content_type, user_id) do
  config = get_aws_s3_config()
  bucket = get_bucket_name()
  filename = create_s3_file_name(file_extension, user_id)
  query_params = [{"ContentType", content_type}]

  ExAws.S3.presigned_url(config, :put, bucket, filename, query_params: query_params)
end
Run Code Online (Sandbox Code Playgroud)

生成的网址如下所示。

https://s3.us-west-1.amazonaws.com/churchapp-la/5/ab49d601efed40e0a6de0509ab78c091.png?ContentType=image%2Fpng&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credentials%2Fus- west-1%2Fs3%2Faws4_request&X-Amz-Date=20200422T230320Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=68e0915ba1abb2722107c96b684e3a62f2e67aae9594bd4dece45 132853f5be2

在客户端我这样做

async function uploadImage(url, data, headers) {
    const response = await fetch(url, {
      method: "PUT",
      headers: headers,
      body: data
    });
    return response;
  }

const handleUpload = e => {
    const formData = new FormData();
    formData.append("image", file);

    const myHeaders = new Headers();
    myHeaders.append("ContentType", file.type);
    uploadImage(presignedUrl, formData, myHeaders)
      .then(data => console.log("Printing uploadImage result: ", data.url))
      .catch(error => {
        console.log("Error: ", error);
      });
  };
Run Code Online (Sandbox Code Playgroud)

当我点击上传时,会调用handleUpload函数并将其上传到S3。但是当我尝试打开文件时,它没有打开。并说签名不符。

我用谷歌搜索了一下。有人说标题应该在后端和前端匹配,我认为我做得正确。

我只设置了 ContentType 并且双方的值相同..

有任何想法吗?请帮忙!

sza*_*oat 0

您应该在两个地方都设置Content-Typeand notContentType作为标头名称。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type