无法在AWS s3上从浏览器上传文件

时间:2018-07-18 12:36:22

标签: node.js amazon-web-services amazon-s3

我正在尝试将数据上传到AWS S3。如果我给Content-Type: false,则会收到错误消息:

At least one of the pre-conditions you specified did not hold</Message><Condition>Bucket POST must be of the enclosure-type multipart/form-data</Condition>

如果我给Content-Type:multipart/form-data,我会得到一个错误:

The body of your POST request is not well-formed multipart/form-data.

这是我的客户端代码:

const file = document.getElementById('file').files[0];

        // let data = e.target;
        const filename = file.name;
        const contentType = file.type;
        const params = [];
        const self = this;
        $.ajax({
            url: self.credentialsUrl,
            type: "GET",
            dataType: "json",
            data: {
                filename: filename,
                content_type: contentType
            },
            success: function(s3Data) {

                const formData = s3Data.params;
                formData["file"] = file;

                $.ajax({
                    type: "POST",
                    url: s3Data.endpoint_url,
                    data: formData,
                    dataType: "xml",
                    contentType: false,
                    processData:false,
                    success: function(resultData){
                        console.log(resultData);
                    },
                    error: function(error){
                        console.log(error);
                    }
                });


            }
        });

我在这个问题上坚持了很长时间,任何帮助将不胜感激。 为了生成signaturepolicy,我关注了这个博客: s3-browser-upload

这是该代码(以防将来不再提供该网址):

    var crypto = require('crypto');

// This is the entry function that produces data for the frontend
// config is hash of S3 configuration:
// * bucket
// * region
// * accessKey
// * secretKey
function s3Credentials(config, filename) {
  return {
    endpoint_url: "https://" + config.bucket + ".s3.amazonaws.com",
    params: s3Params(config, filename)
  }
}

// Returns the parameters that must be passed to the API call
function s3Params(config, filename) {
  var credential = amzCredential(config);
  var policy = s3UploadPolicy(config, filename, credential);
  var policyBase64 = new Buffer(JSON.stringify(policy)).toString('base64');
  return {
    key: filename,
    acl: 'public-read',
    success_action_status: '201',
    policy: policyBase64,
    'x-amz-algorithm': 'AWS4-HMAC-SHA256',
    'x-amz-credential': credential,
    'x-amz-date': dateString() + 'T000000Z',
    'x-amz-signature': s3UploadSignature(config, policyBase64, credential)
  }
}

function dateString() {
  var date = new Date().toISOString();
  return date.substr(0, 4) + date.substr(5, 2) + date.substr(8, 2);
}

function amzCredential(config) {
  return [config.accessKey, dateString(), config.region, 's3/aws4_request'].join('/')
}

// Constructs the policy
function s3UploadPolicy(config, filename, credential) {
  return {
    // 5 minutes into the future
    expiration: new Date((new Date).getTime() + (5 * 60 * 1000)).toISOString(),
    conditions: [
      { bucket: config.bucket },
      { key: filename },
      { acl: 'public-read' },
      { success_action_status: "201" },
      // Optionally control content type and file size
      // {'Content-Type': 'application/pdf'},
      ['content-length-range', 0, 1000000],
      { 'x-amz-algorithm': 'AWS4-HMAC-SHA256' },
      { 'x-amz-credential': credential },
      { 'x-amz-date': dateString() + 'T000000Z' }
    ],
  }
}

function hmac(key, string) {
  var hmac = require('crypto').createHmac('sha256', key);
  hmac.end(string);
  return hmac.read();
}

// Signs the policy with the credential
function s3UploadSignature(config, policyBase64, credential) {
  var dateKey = hmac('AWS4' + config.secretKey, dateString());
  var dateRegionKey = hmac(dateKey, config.region);
  var dateRegionServiceKey = hmac(dateRegionKey, 's3');
  var signingKey = hmac(dateRegionServiceKey, 'aws4_request');
  return hmac(signingKey, policyBase64).toString('hex');
}

module.exports = {
  s3Credentials: s3Credentials
}

0 个答案:

没有答案