使用 multer 将图像上传到 mongoDB Atlas 的策略?
Strategy for uploading images to mongoDB Atlas with multer?
我的目标是能够使用 Multer 将图像上传到 mongoDB Atlas。目前,我已经用express-generator搭建了一个例子,相关文件如下:
app.js:
// ...
var app = express();
//Set up mongoose connection
var mongoose = require('mongoose');
var mongoDB = 'mongodb+srv://username:password@cluster0-wczgu.mongodb.net/test?retryWrites=true&w=majority';
mongoose.connect(mongoDB, { useNewUrlParser: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// ...
index.js:
var express = require('express');
var router = express.Router();
var multer = require("multer");
var fs = require("fs");
var upload = multer({ dest: 'uploads/' })
var Image = require('../models/image');
// GET for image form
router.get("/image/create", function(req, res, next) {
res.render("create_image", {title: "Create Image"});
});
// Uploading image to mongoDB Atlas
router.post("/image/create", upload.single("image"), function(req, res, next) {
var image = new Image({
name: req.body.image_name
});
image.img.data = fs.readFileSync(req.file.path);
image.img.contentType = "image/jpg";
image.save(function(err) {
if (err) { return next(err); }
res.redirect("/");
});
});
// Show some random image
router.get("/image", function(req, res, next) {
Image.findOne({}, function(err, image) {
if (err) { return next(err); }
res.contentType(image.img.contentType)
res.send(image.img.data);
});
});
image.js(图像架构):
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ImageSchema = new Schema(
{
name: {type: String, required: true, max: 100},
img: {data: Buffer, contentType: String}
}
);
module.exports = mongoose.model("Image", ImageSchema);
最后是创建图像的表单create_image.pug:
extends layout
block content
h1= title
form(action="" method="POST" enctype="multipart/form-data")
label(for="image_name") Name of Image:
input#image_name.form-control(type="text" placeholder="Name of image" name="image_name" required="true")
input(type="file" name="image")
button(type='submit') Submit
这工作得很好,因为图像存储在 MongoDB Atlas 中,但它也在本地存储图像。现在从生产的角度来看,这不是一个好主意,因为项目会变得很大。但是我似乎无法弄清楚做这件事的正确方法?
有人能告诉我这样做的正确方法,这样我就可以只将图像存储在 MongoDB Atlas 上,而不是本地吗?也可以告诉我,如果我把这整件事弄错了,应该以完全不同的方式来做这件事吗?
如果您不想在本地存储图像,请使用 MemoryStorage 作为 Multer 存储。
var storage = multer.memoryStorage()
var upload = multer({ storage: storage })
使用内存存储时,文件信息将包含一个名为 buffer
的字段,其中包含整个文件。所以你不必调用 fs.readFileSync
。您可以使用 req.file.image.buffer
访问缓冲区并分配图像数据;
image.img.data = req.file.image.buffer;
我的目标是能够使用 Multer 将图像上传到 mongoDB Atlas。目前,我已经用express-generator搭建了一个例子,相关文件如下:
app.js:
// ...
var app = express();
//Set up mongoose connection
var mongoose = require('mongoose');
var mongoDB = 'mongodb+srv://username:password@cluster0-wczgu.mongodb.net/test?retryWrites=true&w=majority';
mongoose.connect(mongoDB, { useNewUrlParser: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// ...
index.js:
var express = require('express');
var router = express.Router();
var multer = require("multer");
var fs = require("fs");
var upload = multer({ dest: 'uploads/' })
var Image = require('../models/image');
// GET for image form
router.get("/image/create", function(req, res, next) {
res.render("create_image", {title: "Create Image"});
});
// Uploading image to mongoDB Atlas
router.post("/image/create", upload.single("image"), function(req, res, next) {
var image = new Image({
name: req.body.image_name
});
image.img.data = fs.readFileSync(req.file.path);
image.img.contentType = "image/jpg";
image.save(function(err) {
if (err) { return next(err); }
res.redirect("/");
});
});
// Show some random image
router.get("/image", function(req, res, next) {
Image.findOne({}, function(err, image) {
if (err) { return next(err); }
res.contentType(image.img.contentType)
res.send(image.img.data);
});
});
image.js(图像架构):
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var ImageSchema = new Schema(
{
name: {type: String, required: true, max: 100},
img: {data: Buffer, contentType: String}
}
);
module.exports = mongoose.model("Image", ImageSchema);
最后是创建图像的表单create_image.pug:
extends layout
block content
h1= title
form(action="" method="POST" enctype="multipart/form-data")
label(for="image_name") Name of Image:
input#image_name.form-control(type="text" placeholder="Name of image" name="image_name" required="true")
input(type="file" name="image")
button(type='submit') Submit
这工作得很好,因为图像存储在 MongoDB Atlas 中,但它也在本地存储图像。现在从生产的角度来看,这不是一个好主意,因为项目会变得很大。但是我似乎无法弄清楚做这件事的正确方法?
有人能告诉我这样做的正确方法,这样我就可以只将图像存储在 MongoDB Atlas 上,而不是本地吗?也可以告诉我,如果我把这整件事弄错了,应该以完全不同的方式来做这件事吗?
如果您不想在本地存储图像,请使用 MemoryStorage 作为 Multer 存储。
var storage = multer.memoryStorage()
var upload = multer({ storage: storage })
使用内存存储时,文件信息将包含一个名为 buffer
的字段,其中包含整个文件。所以你不必调用 fs.readFileSync
。您可以使用 req.file.image.buffer
访问缓冲区并分配图像数据;
image.img.data = req.file.image.buffer;