将图像上传到S3不起作用

时间:2016-11-27 10:55:50

标签: javascript file-upload amazon-s3 fetch

我正在尝试将文件上传到S3而无需发送到我的服务器。我有一个端点,它给我签名的S3 URL,我可以PUT请求将文件存储到我的桶中。

我试图在JavaScript方面做一些不起作用的事情。 (我没有使用亚马逊的SDK,而不喜欢,因为我正在寻找简单的文件上传,仅此而已)

以下是我目前在JavaScript中尝试做的事情:

uploadToS3 = () => {
    let file = this.state.files[0];
    let formData = new FormData();
    formData.append('Content-Type', file.type);
    formData.append('file', file);
    let xhr = new XMLHttpRequest();
    xhr.open('put', this.signed_url, true);
    xhr.send(formData)
};

我尝试了很多选项,我更喜欢使用fetch,因为我不关心上传进度,因为这些只是图像。我从某个地方使用xhr代码尝试如上所述。这些确实可以进行网络呼叫,看起来应该可以正常工作,但事实并非如此。

以下是发生的事情:在S3上创建一个对象,当我转到公共URL时,它们会被下载,当我使用图像查看器打开它们时,他们说它不是JPG。

我在想我没有正确上传。

以下是我在邮差中的表现:

Postman with file chosen

注意我有正确的签名URL,我已将二进制映像文件附加到请求中。并添加了一个标题,说明内容类型是image / jpeg,如下所示:

Specified headers

当我登录S3并转到我的桶时,我可以看到一个图像,我可以转到它的公共URL并在浏览器中查看。这很完美,正是我想要的,现在我不知道如何在JavaScript上实现相同的目标。

PS:我甚至试图点击postman上的code,它不会为我生成文件代码。

1 个答案:

答案 0 :(得分:1)

此处的问题始于xhr.send(formData)

当您在S3中PUT文件时根本不使用任何表单结构时,只需在请求正文中发送原始对象字节。

Content-Type:和其他元数据位于请求标头中,而不是正文中的表单数据。

在这种情况下,如果您下载上传的文件并使用文本编辑器进行查看,一旦您看到您的代码实际发送到S3的内容后,问题应该非常明显,然后S3会顺从地存储并提供后续请求。

请注意,S3确实支持browser-based form POST uploads,但在执行此操作时,签名过程会有很大不同,需要您创建和签署策略文档,以便您可以发送表单,包括策略和签名,浏览器并允许其他不受信任的用户上传文件 - 签名的策略声明可防止浏览器用户篡改表单并执行您不想要的操作。