AWS - 浏览器上的 PresignedUrl 上传错误,适用于 Postman

AWS - PresignedUrl Upload Error on Browser, Works in Postman

我正在尝试通过 PresignedUrl Lambda 函数将文件上传到我的 S3 存储桶。通过 post 人一切正常。但基于浏览器的应用程序无法显示“SignatureDoesNotMatch”

我的 Lambda 函数区域是 ap-southeast-1。

但类似的功能在 ap-south1(与我的时区相同)中运行良好。知道为什么会这样。这可能与服务器和客户端之间的时区差异有关吗?

请看下面我的代码:

 <script>
    $(document).one('submit', '#memberForm', function (e) {
        e.preventDefault();

        $.get("<FUNCTION URL>", function (data) {

           
            var getUrl = data.uploadURL;
            var fileName = data.fileName;
          
            var theFormFile = $('#fileLogo').get()[0].files[0];
            if (theFormFile != null) {
                console.log(theFormFile);
                $.ajax({
                    type: 'PUT',
                    url: getUrl,
                   
                    contentType: 'binary/octet-stream',
                    
                    processData: false,
                    
                    crossDomain: true,
                   
                    data: theFormFile,
                    success: function () {
                      alert('Yeehaaaw');
                    },
                    error: function (e) {
                        console.log(e);
                        alert('File NOT uploaded');
                        console.log(arguments);
                    }
                });
            } else {
                $("#memberForm").submit();
            }
        });


        return false;
    });

</script>

我的Url生成代码如下:

  'use strict'

const AWS = require('aws-sdk')
AWS.config.update({ region: process.env.AWS_REGION || 'ap-southeast-1' })
const s3 = new AWS.S3()

// Main Lambda entry point
exports.handler = async (event) => {
  console.log("execution started")
  var contentType=event["queryStringParameters"]['contentType']
  var path=event["queryStringParameters"]['path']
  const result = await getUploadURL(contentType,path)
  console.log('Result: ', result)
  return result
}

const getContentType=function(contentType){
    switch(contentType) {
    case "png":
      return "image/png"
    case "jpg":
     return "image/jpeg"
    case "pdf":
     return "application/pdf"
    default:
      return "application/json"
  }
}

const getExtension=function(contentType){
    switch(contentType) {
    case "png":
      return "png"
    case "jpg":
     return "jpg"
    case "pdf":
     return "pdf"
    default:
      return `${contentType}`
  }
}


const getUploadURL = async function(contentType,path) {
  console.log(`Content type is ${contentType}`)
  const actionId = parseInt(Math.random()*10000000)
  
  var type=getContentType(contentType);
  var ext= getExtension(contentType);
  const s3Params = {
    Bucket: process.env.UploadBucket,
    Key:  `${path}/${actionId}.${ext}`,
    ContentType: type,// Update to match whichever content type you need to upload
    ACL: 'public-read', // Enable this setting to make the object publicly readable - only works if the bucket can support public objects,
    Expires: 300
  }
  
  console.log('getUploadURL: ', s3Params)
  return new Promise((resolve, reject) => {
    // Get signed URL
    resolve({
      "statusCode": 200,
      "isBase64Encoded": false,
      "headers": {
        "Access-Control-Allow-Origin": "*"
      },
      "body": JSON.stringify({
          "uploadURL": s3.getSignedUrl('putObject', s3Params),
          "fileName": `${actionId}.${ext}`
      })
    })
  })
}

当我尝试使用 PostMan 时同样有效。

我通过添加签名版本解决了这个问题:

const s3=new AWS.S3({
  signatureVersion:'v4'
});