使用PUT和表单数据将文件上传到S3

时间:2018-03-16 23:01:15

标签: javascript amazon-s3 aws-sdk-js

我正在尝试通过PUT接口将图像文件(jpeg)上传到AWS S3,我收到错误SignatureDoesNotMatch。

在我的服务器上,我有一个带有端点的Express node.js应用程序,用于创建签名网址。



'use strict';

const express = require('express');
const bodyParser = require('body-parser');

const config = require('./config');

// Load the AWS SDK for Node.js
const AWS = require('aws-sdk');
AWS.config.update({
    accessKeyId: config.AWS_ACCESS_KEY_ID, 
    secretAccessKey: config.AWS_SECRET_ACCESS_KEY,
    region: 'us-east-1'
});
const s3 = new AWS.S3();

const app = express();
const awsS3Router = express.Router();

// parse application/json
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// AWS S3 REST endpoints
awsS3Router.get('/getImageDrop', function(req, res) {
    if(!req.query.filename) {
        res.status(400).send('Request query is empty!');
    }
    const s3Params = {
        Bucket: config.S3_BUCKET,
        ContentType: 'image/jpeg',
        ACL: 'public-read',
        Key: req.query.filename,
        Expires: 6000
    };
    s3.getSignedUrl('putObject', s3Params, function(err, data) {
        if(err){
            console.error('ERROR: ' + err);
            return res.end();
        }
        const returnData = {
            signedRequest: data,
            url: 'https://' + config.S3_BUCKET + '.s3.amazonaws.com/' + req.query.filename
        };
        app.locals.s3SignedUrl = returnData.signedRequest;
        res.write(JSON.stringify(returnData));
        res.end();
    });
});
app.use('/aws/s3', awsS3Router);

module.exports = app;




在客户端,我可以调用此端点并获取已签名的S3 URL。响应url格式为: https://[bucket姓名] .s3.amazonaws.com / 878CF5A4-D013-435F-BF7D-F45AB69E580F.jpg?AWSAccessKeyId = [AWS访问密钥]& Content-Type = image%2Fjpeg& Expires = 1521244920& Signature = [签名]&安培; X-AMZ-ACL =公共读

客户端代码具有将文件上载到签名的S3 URL的功能。



async uploadImageToS3BucketAsync(imageFileUri, fileSize, signedUrl) {
        const fileName = PathParse(imageFileUri).base;
        let form = new FormData();
        form.append('files[0]', {
            'uri': imageFileUri,
            'name': fileName,
            'type': 'image/jpeg'
        });
        //form.append('photo', imageFileUri);
        console.info('INFO: PUT ' + signedUrl.signedRequest + ': Request: ' + JSON.stringify(form));
    	return fetch((signedUrl.signedRequest), {
    		method: 'PUT',
            headers: { 'Content-Type': 'image/jpeg', 'Content-Length': fileSize },
            body: form
    	})
    	    .then(function(res) {
                if (res.ok) {
                    console.info('INFO: PUT ' + JSON.stringify(signedUrl) + ': Response: ' + JSON.stringify(res));
                    return res.json();
                } else {
                    console.error('Failed to upload image to S3 bucket!');
                    console.error('ERROR: ' + JSON.stringify(res));
                    alert('Failed to upload image to S3 bucket!!');
                }
            })
            .catch(function(err) {
                console.error('ERROR: Request failed', err);
            });
    }




不幸的是,上传系统失败,出现403错误:



<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
&#13;
&#13;
&#13;

我猜我在PUT调用的请求标头中遗漏了一些内容,但我不确定它是什么。有没有人在node.js找到解决方案?

0 个答案:

没有答案