【问题标题】:Corrupted image on uploading image to AWS-S3 via signed url通过签名 URL 将图像上传到 AWS-S3 时图像损坏
【发布时间】:2020-02-02 16:13:57
【问题描述】:

我正在尝试通过来自 NodeJS 服务器(而不是浏览器)的签名 URL 将图像上传到 aws-s3。要上传的图像已由 NodeJS 生成。我正在从 aws 获取签名 URL 并成功将其上传到 s3。

但我的图像已损坏。出于某种原因,S3 正在向我的图像添加一些标题(比较附加的图像)。

我做错了什么?

获取签名网址:

    try {
        var params = {
            Bucket: bucketName,
            Key: 'FILE_NAME.png',
            Expires: 60
        };
        const url = await s3.getSignedUrlPromise('putObject', params);
        return url;
    } catch (err) {
        throw err;
    }

上传到 s3

        var stats = fs.statSync(filePath);
        var fileSizeInBytes = stats["size"];
        const imageBuffer = fs.readFileSync(filePath);

        var formData = {
            'file': {
                value: imageBuffer,
                options: {
                    filename: 'FILE_NAME.png'
                }
            }
        };

        request({ 
            method: 'put',
            url, 
            headers: {
                'Content-Length': fileSizeInBytes,
                'Content-MD': md5(imageBuffer)           
            }, 
            formData 
        }, function (err, res, body) {
             console.log('body',body);
        });

对比实际图片和上传到s3的图片。 S3 添加了一些头文件:

【问题讨论】:

    标签: node.js amazon-s3 upload pre-signed-url


    【解决方案1】:

    我知道这已经过时了,但我在同一个问题上苦苦挣扎了一段时间。使用预先设定的 url 上传时,请勿使用 new FormData();

    我注意到我在 s3 上的所有文件都比原始文件大 2kb。

    <input type="file" id="upload"/>
    
    var upload = document.getElementById('upload');
    var file = upload.files[0];
    
    //COMMENTED OUT BECAUSE IT WAS CAUSING THE ISSUE
    //const formData = new FormData();
    //formData.append("file", file);
    
    // Assuming axios
    
    const config = {
        onUploadProgress: function(progressEvent) {
            var percentCompleted = Math.round(
                (progressEvent.loaded * 100) / progressEvent.total
            );
            console.log(percentCompleted);
        },
        header: {
            'Content-Type': file.type
        }
    };
    
    axios.put(S3SignedPutURL, file, config)
       .then(async res => {
            callback({res, key})
        })
        .catch(err => {
            console.log(err);
        })
    

    【讨论】:

    • 爱你,伙计:D,我不知道为什么有很多教程和 SO 帖子,而且都使用 new FormData(),谢谢!!
    • 谢谢你!这正是我所需要的。奇怪的是那些额外的 2kb
    • 我希望我能不止一次地支持这个答案。非常感谢!
    • 非常感谢!你知道我们如何使用这种方法上传不同名称的文件吗?
    • 我可以吻你!互联网的其余部分告诉我使用 FormData !
    【解决方案2】:

    我按照上面的 react js 解决方案

    我在上传图片之前所做的是通过 createObject URL,然后将其传递给 API 主体。

    if (e.target.files && e.target.files[0]) {
                let img = e.target.files[0];
                **setImage(URL.createObjectURL(img))**
    

    正确方法:

    if (e.target.files && e.target.files[0]) {
                let img = e.target.files[0];
                **setImage(img)**
    

    为我工作,谢谢 Sam Munroe

    【讨论】:

      【解决方案3】:

      尝试将请求中的内容类型指定为Content-Typemultipart/form-data

      【讨论】:

        猜你喜欢
        • 2022-08-13
        • 2020-04-15
        • 2015-11-14
        • 2017-11-25
        • 1970-01-01
        • 2016-04-14
        • 2021-03-15
        • 1970-01-01
        相关资源
        最近更新 更多