nodejs、multer、aws S3 [英] nodejs, multer, aws S3

查看:39
本文介绍了nodejs、multer、aws S3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何应用 uuid 和日期,以便存储在我的数据库中的文件名和存储在我的 S3 存储桶中的文件名相同?

How do i apply uuid and date so that the filename stored in my database and the filename stored in my S3 bucket are the same?

在当前的实现中,即使帖子是在几个小时后发布的,uuid 和日期也始终相同.

With this current implementation, the uuid and the date are always the same even if a post was made hours later.

有人能帮忙吗,真的很感激.

Can someone help, would really appreciate it.

const s3 = new AWS.S3({
 accessKeyId: process.env.AWS_ID,
 secretAccessKey: process.env.AWS_SECRET,
 region:process.env.AWS_REGION
 })

const uid =uuidv4();
const date =new Date().toISOString()

const multerS3Config = multerS3({
      s3: s3,
      bucket: process.env.AWS_BUCKET,
      metadata: function (req, file, cb) {
               cb(null, { fieldName: file.fieldname }); },
      shouldTransform: true,
      acl: 'public-read',
      contentType: multerS3.AUTO_CONTENT_TYPE,
      transforms: [
                  {
                    id: 'full',
                    key: (req, file, cb) => cb(null, file.originalname 
                         + "-"  + `${date}` + "-" + `${uid}` + 
                         "_full.jpg"),
                    transform: (req, file, cb) => cb(null, 
                               sharp().resize(2000).jpeg({ 
                               quality: 50 }))
                   },
                   {
                     id: 'thumb',
                     key: (req, file, cb) => cb(null, 
                          file.originalname + "-"  + 
                          `${date}` + "-" + `${uid}` + "_thumb.jpg"),
                     transform: (req, file, cb) => cb(null, 
                                sharp().resize(100).jpeg({ 
                                quality: 30 }))
                   },
                   ],
                });

const upload = multer({
storage: multerS3Config,
limits: { fieldSize: 25 * 1024 * 1024 },
});

这是我的帖子请求

router.post(
"/",
 [    upload.array("images", config.get("maxImageCount"))],
 async (req, res) => {
const paths = await req.files.map((file) => ({ originalName: file.originalname + "-" + 
`${date}` 
+ "-" + `${uid}`}));
await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths.map((x) => ({ images: x.originalName })),
},
{ 
include: [Post_Image] }).then(
res.status(201).send())

使用当前的实现,文件将同时存储在 db 和 s3 中.

With this current implementation the the files are getting stored in both the db and s3.

另外,我的另一个问题是使用 multer 和 multer-s3 之间有什么区别?我尝试使用 multer 将图像发布到 s3,但它不起作用,所以我使用了 multer-s3 并且它起作用了.

Also, another question i have is what is the difference between using multer and multer-s3? I tried using multer to post the images to s3 but it did not work so i used multer-s3 and it worked.

更新

 const s3 = new AWS.S3({
 accessKeyId: process.env.AWS_ID,
 secretAccessKey: process.env.AWS_SECRET,
 region:process.env.AWS_REGION
 })

function getFilename() {
return new Date().toISOString() + '-' + uuidv4();
}

function getTransforms() {
const fileName = getFilename();
return {
transforms:[
  {
      id: 'full',
      key: (req, file, cb) => {
        let fname = file.originalname.split(".");
        cb(null, fname[0] + '-' + fileName + "_full.jpg")},
      transform: (req, file, cb) => cb(null,
          sharp().resize(2000).jpeg({
              quality: 50
          }))
  },
  {
      id: 'thumb',
      key: (req, file, cb) => {
        let fname = file.originalname.split(".");
        cb(null, fname[0] + '-' + fileName + "_thumb.jpg")},
      transform: (req, file, cb) => cb(null,
          sharp().resize(100).jpeg({
              quality: 30
          }))
  }
  ],
metadata: (req, file, cb) => {
let fname = file.originalname.split(".");
cb(null, { 
    fieldName: file.fieldname, 
    key: fname[0] + '-' + fileName
});
}}}

const multerS3Config = multerS3({
      s3: s3,
      bucket: process.env.AWS_BUCKET,
      shouldTransform: true,
      acl: 'public-read',
      contentType: multerS3.AUTO_CONTENT_TYPE,
      ...getTransforms()
      });

const upload = multer({
storage: multerS3Config,
limits: { fieldSize: 25 * 1024 * 1024 },
});

这是我的帖子请求

router.post(
"/",
 [    upload.array("images", config.get("maxImageCount"))],
 async (req, res) => {

const paths = await req.files.map((file) => ({ images: 
              file.transforms[0].metadata.key}));

await Post.create({
title: req.body.title,
userId: req.body.userId,
Post_Images: paths,
},
{ 
include: [Post_Image] }).then(
res.status(201).send())

我的问题是 日期和 uuid 变量都将在节点服务器启动时初始化,它永远不会改变,直到您的节点服务器重新启动

推荐答案

快速修复:

  • 保持不变
const s3 = new AWS.S3({
    accessKeyId: process.env.AWS_ID,
    secretAccessKey: process.env.AWS_SECRET,
    region: process.env.AWS_REGION
});

  • dateuuid 变量都会在节点服务器启动时初始化,它永远不会改变,直到你的节点服务器重启,你只需要把它放在一个函数中每次返回新文件名,
  • 此处函数返回除扩展名之外的文件名
    • the date and uuid variables both will initialize when node server start, it will never change until your node server restart, you just need to put it in to a function to return every time new file name,
    • here function returns filename except extension
    • function getFilename() {
          return new Date().toISOString() + '-' + uuidv4();
      }
      

      • 为转换创建函数并从 getFilename() 函数在两个版本中传递相同的文件名,同时在元数据中添加文件名,
        • create function for transforms and pass same filename in both version from getFilename() function, add filename in metadata as well,
        • function getTransforms() {
              const fileName = getFilename();
              return {
                  transforms: [
                      {
                          id: "full",
                          key: (req, file, cb) => {
                              let fname = file.originalname.split(".")
                              cb(null, fname[0] + '-' + fileName + "_full.jpg")
                          },
                          transform: (req, file, cb) => cb(null, sharp().resize(2000).jpeg({ quality: 50 }))
                      },
                      {
                          id: "thumb",
                          key: (req, file, cb) => {
                              let fname = file.originalname.split(".")
                              cb(null, fname[0] + '-' + fileName + "_thumb.jpg")
                          },
                          transform: (req, file, cb) => cb(null, sharp().resize(100).jpeg({ quality: 30 }))
                      }
                  ],
                  metadata: (req, file, cb) => {
                      let fname = file.originalname.split(".");
                      cb(null, { 
                          fieldName: file.fieldname, 
                          key: fname[0] + '-' + fileName + ".jpg"
                      });
                  }
              }
          }
          

          • 调用 getTransforms() 函数,该函数将返回转换和 matadata 属性
          • 我不确定您是否登录以将文件名存储在数据库中,
          • 从我们从元数据传递的transfoems.metadata中获取名称,这将只返回_full name,
            • call getTransforms() function, that will return transforms and matadata properties
            • i am not sure aboutyour login to store filename in database,
            • get name from transfoems.metadata that we passed from metadata, this will return only _full name,
            • router.post("/", async (req, res) => {
              
                  const multerS3Config = multerS3({
                      s3: s3,
                      bucket: process.env.AWS_BUCKET,
                      shouldTransform: true,
                      acl: 'public-read',
                      contentType: multerS3.AUTO_CONTENT_TYPE,
                      ...getTransforms()
                  });
              
                  const upload = multer({
                      storage: multerS3Config,
                      limits: { fieldSize: 25 * 1024 * 1024 }
                  });
              
                  upload.array("images", config.get("maxImageCount"))(req, res, async(error) => {
                      const paths = await req.files.map((file) => ({
                          images: file.transforms[0].metadata.key
                      }));
                      await Post.create({
                          title: req.body.title,
                          userId: req.body.userId,
                          Post_Images: paths,
                      }, {
                          include: [Post_Image]
                      })
                  });
                  
              })
              


              基本上声明multer-s3 Streaming multer storage engine for AWS S3.足以区分multer和multer-s3.


              Basically the statement multer-s3 Streaming multer storage engine for AWS S3. is enough to differentiate both multer and multer-s3.

              该代码尚未经过测试,您可以解决此问题,看看会发生什么!

              The code has not been tested, you can workaround and see what's happen!

              这篇关于nodejs、multer、aws S3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆