nodejs, multer, aws S3

#javascript #node.js #amazon-s3 #uuid #multer-s3

#javascript #node.js #amazon-s3 #uuid #multer-s3

Вопрос:

Как мне применить uuid и date, чтобы имя файла, хранящееся в моей базе данных, и имя файла, хранящееся в моей корзине S3, совпадали?

В этой текущей реализации uuid и дата всегда одинаковы, даже если сообщение было сделано несколько часов спустя.

Может кто-нибудь помочь, был бы очень признателен.

 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 },
});
 

Вот мой запрос post

 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())
 

Благодаря этой текущей реализации файлы сохраняются как в БД, так и в s3.

Кроме того, у меня есть еще один вопрос: в чем разница между использованием multer и multer-s3? Я пытался использовать multer для публикации изображений в s3, но это не сработало, поэтому я использовал multer-s3, и это сработало.

Обновить

  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 },
});
 

Вот мой запрос post

 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())
 

Моя проблема в том the date and uuid variables both will initialize when node server start, it never changes until your node server restarts

Комментарии:

1. Я постараюсь пройти через это.

2. @Arya действительно ценю это, я просто хочу, чтобы мое имя файла в db и в s3 было уникальным и одинаковым, чтобы я мог отображать изображения из s3

3. @Arya тебе удалось пройти через это?

4. я много пробовал, но не смог этого сделать

5. Ко второму вопросу: multer является ли промежуточное программное обеспечение для анализа файлов из входящих запросов POST. multer-s3 является ли multer автоматической загрузкой в S3, multer-s3-transform является ли multer S3 пакетными преобразованиями 😉

Ответ №1:

Быстрые исправления:

  • остаются прежними
 const s3 = new AWS.S3({
    accessKeyId: process.env.AWS_ID,
    secretAccessKey: process.env.AWS_SECRET,
    region: process.env.AWS_REGION
});
 
  • date uuid обе переменные и будут инициализироваться при запуске сервера узла, они никогда не изменятся, пока ваш сервер узла не перезапустится, вам просто нужно ввести его в функцию, чтобы возвращать каждый раз новое имя файла,
  • здесь функция возвращает имя файла, кроме расширения
 function getFilename() {
    return new Date().toISOString()   '-'   uuidv4();
}
 
  • создайте функцию для преобразований и передайте одно и то же имя файла в обеих версиях из getFilename() функции, также добавьте имя файла в метаданные,
 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,
 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]
        })
    });
    
})
 

В принципе, для AWS S3 достаточно оператора multer-s3 Streaming multer storage engine., чтобы различать как multer, так и multer-s3.

Код не был протестирован, вы можете обойти и посмотреть, что произойдет!

Комментарии:

1. кд, как только он будет закодирован, у него будет uid, для его регистрации вам нужно рекурсивно упорядочить объект. вы его тестировали / отлаживали?

2. @Pogrindis да, но это не работает. Я просто хочу, чтобы uuid и дата были одинаковыми для каждого файла, загруженного в базу данных и s3.

3. @turivishal ЭТО СРАБОТАЛО 🙂 ваша легенда, большое вам спасибо, я действительно очень ценю вашу помощь. Надеюсь, у вас был замечательный день