首页 > 解决方案 > 使用单个 Lambda 函数将多种文件类型上传到 S3

问题描述

我希望用户能够将 JPG 或 PNG 图像上传到 S3 存储桶。

我正在使用一个 Lambda 函数,它只允许我.jpg为 S3 预签名图像,它只适用于一种文件类型。如何添加其他文件类型来预签名,例如.png图像。我真的需要编写一个新的 Lambda,我只需将其更改为.jpg.png或者我可以在下面的现有代码中以某种方式完成吗?

const AWS = require('aws-sdk')
AWS.config.update({ region: process.env.REGION })
const s3 = new AWS.S3();

const uploadBucket = 'xxx-bucket'

exports.handler = async (event) => {
  const result = await getUploadURL()
  console.log('Result: ', result)
  return result
};

const getUploadURL = async function() {
  console.log('getUploadURL started')
  let actionId = Date.now()

  var s3Params = {
    Bucket: uploadBucket,
    Key:  `${actionId}.jpg`,
    ContentType: 'image/jpeg',
    CacheControl: 'max-age=31104000',
    ACL: 'public-read',
  };

  return new Promise((resolve, reject) => {
    // Get signed URL
    let uploadURL = s3.getSignedUrl('putObject', s3Params)
    resolve({
      "statusCode": 200,
      "isBase64Encoded": false,
      "headers": {
        "Access-Control-Allow-Origin": "*"
      },
      "body": JSON.stringify({
          "uploadURL": uploadURL,
          "photoFilename": `${actionId}.jpg`
      })
    })
  })
}

标签: amazon-web-servicesamazon-s3aws-lambdaserverless

解决方案


您的选择如下:

  • 按照您的建议制作一个新的 Lambda 以单独处理 PNG
  • getUploadURL通过您的事件将参数传递给您的函数,例如:
exports.handler = async event => {
  const { filetype } = event.body (or pathParams, query string, etc)
  const result = await getUploadURL(filetype)
  console.log('Result: ', result)
  return result
};

const getUploadURL = async filetype => {
  console.log('getUploadURL started')
  let actionId = Date.now()

  var s3Params = {
    Bucket: uploadBucket,
    Key:  `${actionId}.${filetype}`,
    ContentType: `image/${filetype === 'jpg'?'jpeg':'png'}`,
    CacheControl: 'max-age=31104000',
    ACL: 'public-read',
  };

...

对 S3.getSignedUrl() 的调用{Bucket: 'bucket', Key: 'key'}至少需要 putObject 操作。因此,如果您不想牺牲文件扩展名和/或内容类型属性,那么这些是唯一的选择。

AWS 文档


推荐阅读