Я пытаюсь сделать следующее в Node.js, используя экспресс-маршрутизатор, Multer-S3, Multer, AWS и Mongodb.

Я хочу: 1: Проверить, является ли тип файла изображение, цена - число и т. Д. (Какая-то проверка качества) 2: Если указано выше, загрузить изображение на S3, чтобы получить URL-адрес изображения 3: Если URL-адрес изображения был создан, загрузите его в Mongodb, включая URL созданного изображения ..

Попытка использовать приведенный ниже код, но может заставить работать только один из них одновременно.

const express = require("express");
const router = express.Router();

const shopController = require("../controllers/shop");

router.post(
  "/shop/create/:shopId",
  shopController.creatingShop,
  shopController.createShopItem
);
const ShopItem = require("../models/shopitem"); //Mongoose Schema

const multer = require("multer");
const fileview = multer().single("file1"); //Trying to use this to view file before uploading to S3

const uploader = require("../services/file-upload");
const singleUpload = uploader.single("file1"); //Using this to upload to S3

exports.createShopItem = (req, res, next) => {
  fileview(req, res, function (err) {
    const file = req.file;
    const title = req.body.title;
    const price = req.body.price;
    const description = req.body.description;
    const location = req.body.location;
    const user = "OrreSnorre";

    if (
      file.mimetype != "image/jpeg" &&
      file.mimetype != "image/jpg" &&
      file.mimetype != "image/png"
    ) {
      return next(new Error("invalid file type"));
    }

    if (file.size > 2500000) {
      return next(new Error("Your image is to big. Maximum 2.5mb"));
    }
    next();
    console.log(
      "Here I want to add upload text to mongoDb... including URL from S3 after it is generated"
    );
   
  });

exports.creatingShop = (req, res, next) => {
  singleUpload(req, res, function (err) {
    console.log(req.file);
    // res.json({ "image-url": req.file.location });
  });
  next();
};

У кого-нибудь есть идеи? Или примеры, которые работают?

С уважением, Оскар

0
Oscar Ekstrand 16 Мар 2021 в 09:21

1 ответ

Лучший ответ

Это можно сделать двумя способами: вы можете использовать только multer или multer-s3.

Для простоты я покажу вам способ, используя только multer.

Процесс обработки следующий:

  1. Обработка Multer и сохранение на локальном
  2. Вы читаете локально и загружаете в s3 с помощью s3 SDK (вы должны изучить, как удалить файл после загрузки, но я не буду загромождать вас этой логикой здесь)
  3. Если загрузка прошла успешно, вы получаете URL-адрес и передаете его в свою MongoDB.
    // Make "temp" directory as multer.diskStorage wont create folder
    fs.mkdir('./temp', { recursive: true }, (err) => {
      if (err) throw err;
    });
    const PORT = parseInt(process.argv[2]) || parseInt(process.env.PORT) || 3000;
    // Multer
    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, './temp');
      },
      filename: function (req, file, cb) {
        let extArray = file.mimetype.split('/');
        let extension = extArray[extArray.length - 1];
        cb(null, new Date().getTime() + '.' + extension);
      },
    });
    
    const upload = multer({ storage: storage });
    
    const endpoint = new AWS.Endpoint(AWS_S3_HOSTNAME);
    const s3 = new AWS.S3({
      endpoint,
      accessKeyId: AWS_S3_ACCESSKEY_ID,
      secretAccessKey: AWS_S3_SECRET_ACCESSKEY,
    });
    
    // Get the uploaded file in local here
    const readFile = (path) =>
      new Promise((resolve, reject) =>
        fs.readFile(path, (err, buff) => {
          if (null != err) reject(err);
          else resolve(buff);
        })
    
    // Upload to AWS S3 here
    const putObject = (file, buff, s3) =>
      new Promise((resolve, reject) => {
        const params = {
          Bucket: AWS_S3_BUCKET_NAME,
          Key: file.filename,
          Body: buff,
          ACL: 'public-read',
          ContentType: file.mimetype,
          ContentLength: file.size,
        };
        s3.putObject(params, (err, result) => {
          if (null != err) reject(err);
          else resolve(file.filename);
        });
      });
      );
    
    const mongoClient = new MongoClient(MONGO_URL, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    app.post('/api/post', upload.single('imageFile'), async (req, res) => {
    readFile(req.file.path)
            .then((buff) =>
              // Insert Image to S3 upon succesful read
              putObject(req.file, buff, s3)
            )
            .then((results) => {
              // build url of the resource upon successful insertion
              const resourceURL = `https://${AWS_S3_BUCKET_NAME}.${AWS_S3_HOSTNAME}/${results}`;
              const doc = {
                comments,
                title,
                ts: new Date(),
                image: resourceURL, // Your URL reference to image here
              };
              // Insert to your mongoDB
              mongoClient
                .db(MONGO_DB)
                .collection(MONGO_COLLECTION)
                .insertOne(doc)
                .then((results) => {
                  // delete the temp file when no error from MONGO & AWS S3
                  fs.unlink(req.file.path, () => {});
                  // return the inserted object
                  res.status(200).json(results.ops[0]);
                })
                .catch((error) => {
                  console.error('Mongo insert error: ', error);
                  res.status(500);
                  res.json({ error });
                });
            })
            .catch((error) => {
              console.error('insert error: ', error);
              res.status(500);
              res.json({ error });
            });
}

0
Darkripper 16 Мар 2021 в 06:49