【问题标题】:Prevent Javascript adding metadata on File Upload to S3防止 Javascript 在文件上传到 S3 时添加元数据
【发布时间】:2020-11-06 10:12:21
【问题描述】:

基本上我愿意通过浏览器将文件直接上传到 S3,即没有任何网络服务器充当这样的中间件或代理。

所以我使用 boto3 库生成预签名 URL,如下所示:

def put_url(self, key):
    url = self.client.generate_presigned_url(
        ClientMethod="put_object",
        Params={
            "Bucket": "visweswaran",
            "Key": key
        }
    )
    return url

这会返回一个完全没问题的预签名 URL。我正在使用 JQuery 向 S3 发出 ajax PUT 请求以上传我的文件。

                let file_data = document.getElementById("file_data").files[0];
                var form = new FormData();
                form.append("", file_data, "test.txt");
                var settings = {
                  "url": url,
                  "method": "PUT",
                  "timeout": 0,
                  "processData": false,
                  "mimeType": "multipart/form-data",
                  "contentType": "text/plain",
                  "beforeSend": function(xhr){xhr.setRequestHeader('Content-Disposition', 'attachment');},
                  "data": form
                };
                $.ajax(settings).done(function (response) {
                  location.reload();
                });

文件通过浏览器成功上传到 S3。但是当我打开文件时,我看到奇怪的元数据像这样被添加到文件的顶部,

-----------------33057860671031084693134041830 内容处置:表单数据;名称=“名称”

test.txt -----------------------------33057860671031084693134041830 内容处置:表单数据;名称=“文件”;文件名="test.txt" 内容类型:text/plain

我也尝试过更正式的解决方案,例如 Pluploader (https://www.plupload.com/),我也面临同样的问题。我希望有人指出我正确的方向来解决它。非常感谢 Ant 的帮助。

参考资料:

  1. https://softwareontheroad.com/aws-s3-secure-direct-upload/
  2. How to upload to AWS S3 directly from browser using a pre-signed URL instead of credentials?

工作解决方案

我已经用视频进行了测试,您不需要表格。直接发送数据就行了

let video = document.getElementById("video_file").files[0];
var settings = {
    "url": url,
    "method": "PUT",
    "timeout": 0,
    "processData": false,
    "data": video
};
$.ajax(settings).done(function (response) {
    location.reload();
});

【问题讨论】:

  • 我建议使用 POST 而不是 PUT 从浏览器上传文件。您可以改用generate_presigned_post 来为前端表单生成所需的字段值。这是一个很棒的tutorial,告诉你如何一步一步来。
  • 您可以尝试在不使用 formData 的情况下发送 PUT 请求吗? data 属性将具有file_data 的引用,并且签名和发送(ajax)时的内容类型可以是ContentType: 'binary/octet-stream'
  • 如果删除 "mimeType": "multipart/form-data",xhr.setRequestHeader('Content-Disposition', 'attachment'); 会发生什么?
  • @FelixKling 我已经删除了 mimeType 并且我看到了同样的东西 ---------------------------- -261461442633876784451364777288 内容处置:表单数据;名称=""; filename="test.txt" 内容类型:文本/纯文本

标签: javascript jquery python-3.x amazon-s3 boto3


【解决方案1】:

我尝试使用两种方法上传带有预签名放置 URL 的 txt 文件:

  1. 发送表单数据:(这用于 POST url 而不是 PUT
  • 这实际上将content-disposition 标头添加到问题中提到的最终文件中。
  1. 发送原始二进制数据(推荐的方式以及 PUT url 的使用方式!):
  • 文件已正确上传,并且不包含content-disposition 标头。

您可以尝试在不使用formData 的情况下发送PUT 请求吗?

ajax 的data 属性的值应该是file_data,而content-type 应该是ContentType: 'binary/octet-stream',而签署S3 URL 和发送(ajax)应该是ContentType: 'binary/octet-stream'

如果需要使用 formData,请查看 S3 的 preSignedPost。

【讨论】:

  • 我听不懂你的回答,我已经更改了内容类型,但数据属性是文件内容所在的位置还是我遗漏了什么?
  • 是的,数据属性是文件内容所在的位置。我想说的是您应该在该属性中发送文件的原始二进制数据,而不是 formData 对象。我已经编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 2021-03-02
  • 1970-01-01
  • 2016-12-13
相关资源
最近更新 更多