通过签名的URL将图像上传到AWS-S3时图像损坏

时间:2019-10-04 10:17:46

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

我正在尝试通过签名URL从NodeJS服务器(而不是从浏览器)将图像上传到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添加了一些标题:

compare

3 个答案:

答案 0 :(得分:5)

我知道这已经很老了,但是我为同一问题苦了一段时间。使用预先指定的网址上传时,请勿使用新的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);
    })

答案 1 :(得分:0)

尝试一下,它将为您服务

const AWS = require('aws-sdk')
const uuidv1 = require('uuid/v1')
const mime = require('mime-types')
const FIVE_MINUTES = 5 * 60
const CONTENT_BUCKET = process.env.REACT_APP_CONTENT_BUCKET

const s3 = new AWS.S3({
    'accessKeyId': xxxxxxxxxxxxxxxxxxxxxxxxxx, // Access KEy
    'secretAccessKey': xxxxxxxxxxxxxxxxxxxxxxxxxxx,// Secret Key
    'region': 'us-east-1'
})

export const getSignedUrl = (filename) => {
    const defaultExt = 'png'
    let extension = filename.match(/\.(\w+$)/)
    extension = extension.length > 1 ? extension[1] : defaultExt

    let responseParams = {
        'contentStorageKey': uuidv1() + '-' + filename,
        'contentStorageBucketName': CONTENT_BUCKET,
        'contentType': mime.contentType(extension)
    }

    const params = {
        Bucket: responseParams.contentStorageBucketName,
        Key: responseParams.contentStorageKey,
        Expires: FIVE_MINUTES,
        ContentType: responseParams.contentType,
        ACL: 'public-read'
    }

    try {
        const presignedURL = s3.getSignedUrl('putObject', params)
        return { ...responseParams, presignedURL }
    } catch (ex) {
        console.error(ex)
        throw ex
    }
}

答案 2 :(得分:0)

尝试将请求中的内容类型指定为dnsmasq Tue Oct 22 17:17:16 2019 PUSH: Received control message: 'PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 169.254.169.253,dhcp-option DNS 10.0.0.2,route 10.8.0.1,topology net30,ping 10,ping-restart 120,ifconfig 10.8.0.6 10.8.0.5,peer-id 0,cipher AES-256-GCM' dhcp-option DNS 169.254.169.253 dhcp-option DNS 10.0.0.2