Express Router - 上传到 S3 和 MongoDb

Express Router - uploading to S3 and MongoDb

我正尝试在 Node.js 中使用 Express 路由器、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();
};

有人有想法吗?或者有效的例子?

此致, 奥斯卡

有两种方法可以做到这一点,您可以只使用 multermulter-s3

为简单起见,我将向您展示仅使用 multer 的方法。

处理流程如下:

  1. 多进程并保存到本地
  2. 你从本地读取,然后使用 s3 SDK 上传到 s3(你也应该探索如何在上传后删除文件,但我不会在这里用这个逻辑让你混乱)
  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 });
            });
}