繁体   English   中英

Node.js 使用 multer 将图像上传到 MongoDb 和 Amazon s3

[英]Node.js uploading image with multer to both MongoDb and Amazon s3

我一直在尝试在 Node.js 中使用 MVC 结构来构建一个既上传到 Mongodb 以及 Amazon S3 的发布路由。

我在下面构建以帮助我上传到 S3。

const aws = require("aws-sdk");
const multer = require("multer");
const multerS3 = require("multer-s3");
require("dotenv").config();

aws.config.update({
  secretAccessKey: process.env.AMAZON_SECRET_ACCESS_KEY,
  accessKeyId: process.env.AMAZON_ACCESS_KEY,
  region: "eu-north-1",
});

const s3 = new aws.S3();

const uploader = multer({
  storage: multerS3({
    s3: s3,
    bucket: "shopitemimages",
    acl: "public-read",
    contentType: multerS3.AUTO_CONTENT_TYPE,
    metadata: function (req, file, cb) {
      cb(null, { fieldName: "lets see what we want as fieldvalue" });
    },
    key: function (req, file, cb) {
      cb(null, Date.now().toString());
    },
  }),
});

module.exports = uploader;

如果它像下面这样在自己的路线中使用它,它就像一个魅力。

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

const uploader = require("../services/file-upload");

const singleUpload = uploader.single("file1");

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

module.exports = router;

但是,当我尝试使用 MVC 结构将它与另一个中间件一起使用时,下面的代码适用于上传到 Mongodb,但不适用于 S3 .. 它说成功但没有上传任何内容。

这是路线:

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


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

router.post(
  "/shop/create/:shopId",
  upload.single("file1"),//this seems to be needed, otherise I can't parse the file for mongodb upload
  shopController.createShopItem //controller doing the actual work
);

这是我试图在上述路线中使用的 controller:

const ShopItem = require("../models/shopitem");
const uploader = require("../services/file-upload");
const singleUpload = uploader.single("file1");


exports.createShopItem = (req, res, next) => {
  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"
  ) {
    next(new Error("invalid file type"));
  }
//this is the part where I try to upload to S3
  singleUpload(req, res, (err) => {
    console.log("iwas here");
    console.log(req.file);
    return res.json({ "image-url": req.file.location });
  });
  const newItem = new ShopItem({
    title: title,
    price: price,
    description: description,
    location: location,
    user: user,
  });

  newItem
    .save()
    .then((res) => console.log("saved"))
    .catch((err) => {
      const error = new Error(err);
      error.httpStatusCode = 500;
      return next(error);
    });
};

有什么我不明白的建议吗?

我花了几天的业余时间来做这个..让我们看看是否有人更快;-)

最好的问候,奥斯卡

在测试您的代码后,我注意到您做错了什么,它们是;

  1. 常量上传 = multer(); 创建 multer 实例而不向其传递参数(如 bucketID 和 s3 凭据),因此当您尝试使用该实例时不会发生任何事情,因为您在这里尝试使用它upload.single("file1") 相反,您也应该在路由中调用中间件。
  2. 您声明了 singleUpload ,而没有在 controller 的任何地方调用它。

所以我对你的代码做了一些修改,虽然使用谷歌 GCS,因为我没有 S3 帐户来测试,但我相信它也适用于 s3,你也可以创建 GCS 帐户来测试。

控制器/shop.js

//const ShopItem = require("../models/shopitem");
 const uploader = require("../services/file-upload");
 const singleUpload = uploader.single("file1");


exports.createShopItem = (req, res, next) => {
  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";
  console.log("file.mimetype-->",file.mimetype);
  if (
     file.mimetype != "image/jpeg" &&
     file.mimetype != "image/jpg" &&
     file.mimetype != "image/png"
  ) {
    next(new Error("invalid file type"));
  }
    console.log("----------------------");
    console.log("if you can see this location: ",location);
    console.log("that means you can store into your mongodb");
    console.log("-----------------------");
    return res.json({ "image-url": req.file.location });

};

服务/文件上传.js

const aws = require("aws-sdk");
const multer = require("multer");
const multerS3 = require("multer-s3");
const multerGoogleStorage =require('multer-cloud-storage');

require("dotenv").config();

aws.config.update({
 secretAccessKey: process.env.AWS_ACCESS_KEY,
 accessKeyId: process.env.AWS_ACCESS_KEY_ID,
 region: "eu-north-1",
});

const s3 = new aws.S3();

const uploader_ = multer({
   storage: multerS3({
    s3: s3,
    bucket: "shopitemimages",
    acl: "public-read",
    contentType: multerS3.AUTO_CONTENT_TYPE,
    metadata: function (req, file, cb) {
     console.log("this is the file",file);
     cb(null, { fieldName: "lets see what we want as fieldvalue" });
    },
    key: function (req, file, cb) {
     cb(null, Date.now().toString());
    },
  }),
});
const uploader = multer({
  storage: multerGoogleStorage.storageEngine({
   autoRetry: true,
   bucket: 'buck-name',
   projectId: 'projectid',
   keyFilename: 'pathtokeyfile.json',
   filename: (req, file, cb) => {
       cb(null, `/${Date.now()}${file.originalname}`);
       console.log(file);
    // output = output.replace(/{%DESCRIPTION%}/g, product.description);
   }
 }),
});

module.exports = uploader;

路由.js

 const express = require("express");
 const router = express.Router();
 const multer = require("multer");
 // const upload = multer();


 const shopController = require('./controllers/shop');
 const uploader = require("./services/file-upload");
 router.post(
   "/shop/create/:shopId",
   uploader.single("file1"),// I changed this to object from your middleware
   shopController.createShopItem //controller doing the actual work
 );
module.exports = router;

服务器.js

const express = require("express");
const http = require("http");
const port = process.env.PORT || 3000;
//setup app & its routes
const app = express();
const routes = require('./route');
app.use(routes);

//start http server
const httpServer = http.createServer(app);
httpServer.listen(port);

let serviceName ="Upload service"
console.log(`[${serviceName}] http server listening at port ${port}`);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM