node.js - 使用不带中间件功能的multer上载到S3

标签 node.js express amazon-s3 multer multer-s3

我正在使用multer将媒体上传到我的s3存储桶。我正在使用multer-s3作为中间件来上传媒体,例如:

const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: myBucket,
    key: function (req, file, cb) {
      cb(null, new Date().getTime() + '_' + file.originalname)
    }
  })
});
并在路由中将其称为:
router.post("/media",upload.single("media"))
这很好用。但是,对我不起作用的情况是:假设我上传了一个图像,并且我想通过在上载之前调整其大小来存储图像的多个版本。我无法像正常情况那样调用上传功能。我想做类似的事情:
let thumbnail = myFunctionToReturnImageFile(req.file);
upload(thumbnail);
我知道我需要发送一些多部分/形式部分,但我找不到解决方案。如果您建议我做某事,那将会很棒。

最佳答案

选项1 -使用multer-s3-transform中间件通过文件转换来处理S3上传,例如使用sharp调整图像大小。

const multer = require('multer')
const multerS3 = require('multer-s3-transform')
const sharp = require('sharp')
const AWS = require('aws-sdk')
const S3 = new AWS.S3({
    accessKeyId: ...,
    secretAccessKey: ...
})

const upload = multer({
  storage: multerS3({
    s3: S3,
    bucket: ...,
    shouldTransform: true,
    transforms: [
      {
        id: 'original',
        key: (req, file, cb) => cb(null, new Date().getTime() + '_' + req.file.originalname),
        transform: (req, file, cb) => cb(null, sharp().jpg())
      },
      {
        id: 'large',
        key: (req, file, cb) => cb(null, new Date().getTime() + '_large_' + req.file.originalname),
        transform: (req, file, cb) => cb(null, sharp().resize(1200, 900).jpg())
      },
      {
        id: 'small',
        key: (req, file, cb) => cb(null, new Date().getTime() + '_small_' + req.file.originalname),
        transform: (req, file, cb) => cb(null, sharp().resize(400, 300).jpg())
      }
    ]
  })
})

router.post('/media', upload.single('media'))
选项2 -如果您坚持手动操作,则可以使用简单的multer处理传入的文件,使用sharp调整其大小,然后使用AWS-SDK将每个调整大小的文件上载到S3。
const multer = require('multer')
const sharp = require('sharp')
const AWS = require('aws-sdk')
const S3 = new AWS.S3({
    accessKeyId: ...,
    secretAccessKey: ...
})

router.post('/media', multer().single('media'), (req, res) => {
  // req.file represents the uploaded file
  let time = new Date().getTime()
  
  Promise.all([
    // original file
    S3.upload({
      Bucket: ...,
      Key: time + '_' + req.file.originalname,
      Body: req.file.buffer
    }),
    
    // large preview
    sharp(req.file)
      .resize(1200, 900)
      .toBuffer()
      .then(resized => S3.upload({
        Bucket: ...,
        Key: time + '_large_' + req.file.originalname,
        Body: resized
      }).promise()),
    
    // small thumbnail
    sharp(req.file)
      .resize(400, 300)
      .toBuffer()
      .then(resized => S3.upload({
        Bucket: ...,
        Key: time + '_small_' + req.file.originalname,
        Body: resized
      }).promise()),
  ])
  .then(() => res.send("Images uploaded"))
  .catch(e => {
    console.warn(e) // debug this error
    res.status(500).send("Unable to upload images")
  })
})

关于node.js - 使用不带中间件功能的multer上载到S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64900983/

相关文章:

javascript - 有没有一种方法可以找到时间序列中超过 X% 时间的 Y 值?

python - 永远运行 Python 脚本,记录错误并在崩溃时重新启动

node.js - 如何使用express进入ejs中的调试器?

javascript - 使用 Nodejs 和 Express 进行异步调用

javascript - AWS S3 对象列表

javascript - Node中如何使用TCP与其他应用交互

node.js - Nodejs Http请求没有响应

javascript - express.route 如何确定路线

python - 我将如何使用 boto3 在 s3 存储桶上的 aws 文件上传成功响应?

symfony - 尝试使用 gaufrette 上传到 S3 时出错