使用 express 将图像上传和检索到 mongoDB 时出现问题
issue with uploading and retriving images to mongoDB using express
我正在构建一个初学者全栈项目,我正在其中创建一个网上商店。在这里,我有一个管理路线,我可以在其中将新产品上传到我的 mongoDB 数据库,以便它们在商店中展示。与任何优秀的网上商店一样,我需要图片来展示我的产品,但我很难为该功能编写代码。我知道有一个叫做 GridFS 的东西,但是我的图像永远不会超过 16 MB,所以我不想让我的解决方案过于复杂。
请参阅我的代码中箭头下方的注释,了解我遇到的具体问题
我的产品架构:
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
productName: {type: String, required: true, unique: true},
image: {data: Buffer, contentType: String},
price: {type: Number, required: true}
}, {timestamps: true});
module.exports = mongoose.model("Product", UserSchema);
添加新产品路线:
const router = require("express").Router(); //
const Product = require("../models/Product"); //
//
router.post("/add", async (req, res) => { // // //
const newProduct = new Product({ // / //
productName: req.body.productName, //
image: { // this is where I have no idea what I am doing
data: req.body.image, // req.body.image is just the filename, do I need the entire path?
contentType: 'image/png' // not all images are png, how do I update this depending on image type?
},
price: req.body.price
});
try {
const savedProduct = await newProduct.save();
res.redirect("../products");
} catch (err) {
console.log(err);
console.log("an error occured when adding product");
res.redirect(400, "../products");
}
});
显示产品页面:
<% products.forEach(product => { %>
<article>
<h2><%= product.productName %></h2>
<div class="price"><%= product.price %></div>
<img src="<%= product.image %>" alt="">
</article>
<% }) %>
您可以使用像 express-fileupload
这样的中间件包来处理文件上传。这是包 Link.
的文档
假设图像的输入名称是 image
,您可以从 req.files.image
访问图像的信息。此对象包含缓冲区中表示的文件及其 mimetype。现在您可以像这样将这两个信息存储在数据库中:
router.post("/add", async (req, res) => {
const img = req.files.image;
const newProduct = new Product({
productName: req.body.productName,
image: {
data: img.data, // buffer
contentType: img.mimetype
},
price: req.body.price
});
try {
const savedProduct = await newProduct.save();
res.redirect("../products");
} catch (err) {
console.log(err);
console.log("an error occured when adding product");
res.redirect(400, "../products");
}
});
当您想在html页面上显示此图像时,您必须将缓冲区转换为base64 表示。您可以简单地对从数据库检索的缓冲区数据使用 .toString("base64")
。 src
的值应采用这种格式 data:[<mediatype>][;base64],<data>
referance:
<% products.forEach(product => { %>
<article>
<h2><%= product.productName %></h2>
<div class="price"><%= product.price %></div>
<img src="data:<%= product.image.contentType%>;base64,<%= product.image.data.toString('base64')%>" alt="">
</article>
<% }) %>
我没试过,但如果 ejs 文件中的代码抛出错误,请尝试将图像以 base64 编码存储在数据库中,然后直接在 ejs 文件中使用 product.image.data
我正在构建一个初学者全栈项目,我正在其中创建一个网上商店。在这里,我有一个管理路线,我可以在其中将新产品上传到我的 mongoDB 数据库,以便它们在商店中展示。与任何优秀的网上商店一样,我需要图片来展示我的产品,但我很难为该功能编写代码。我知道有一个叫做 GridFS 的东西,但是我的图像永远不会超过 16 MB,所以我不想让我的解决方案过于复杂。
请参阅我的代码中箭头下方的注释,了解我遇到的具体问题
我的产品架构:
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
productName: {type: String, required: true, unique: true},
image: {data: Buffer, contentType: String},
price: {type: Number, required: true}
}, {timestamps: true});
module.exports = mongoose.model("Product", UserSchema);
添加新产品路线:
const router = require("express").Router(); //
const Product = require("../models/Product"); //
//
router.post("/add", async (req, res) => { // // //
const newProduct = new Product({ // / //
productName: req.body.productName, //
image: { // this is where I have no idea what I am doing
data: req.body.image, // req.body.image is just the filename, do I need the entire path?
contentType: 'image/png' // not all images are png, how do I update this depending on image type?
},
price: req.body.price
});
try {
const savedProduct = await newProduct.save();
res.redirect("../products");
} catch (err) {
console.log(err);
console.log("an error occured when adding product");
res.redirect(400, "../products");
}
});
显示产品页面:
<% products.forEach(product => { %>
<article>
<h2><%= product.productName %></h2>
<div class="price"><%= product.price %></div>
<img src="<%= product.image %>" alt="">
</article>
<% }) %>
您可以使用像 express-fileupload
这样的中间件包来处理文件上传。这是包 Link.
假设图像的输入名称是 image
,您可以从 req.files.image
访问图像的信息。此对象包含缓冲区中表示的文件及其 mimetype。现在您可以像这样将这两个信息存储在数据库中:
router.post("/add", async (req, res) => {
const img = req.files.image;
const newProduct = new Product({
productName: req.body.productName,
image: {
data: img.data, // buffer
contentType: img.mimetype
},
price: req.body.price
});
try {
const savedProduct = await newProduct.save();
res.redirect("../products");
} catch (err) {
console.log(err);
console.log("an error occured when adding product");
res.redirect(400, "../products");
}
});
当您想在html页面上显示此图像时,您必须将缓冲区转换为base64 表示。您可以简单地对从数据库检索的缓冲区数据使用 .toString("base64")
。 src
的值应采用这种格式 data:[<mediatype>][;base64],<data>
referance:
<% products.forEach(product => { %>
<article>
<h2><%= product.productName %></h2>
<div class="price"><%= product.price %></div>
<img src="data:<%= product.image.contentType%>;base64,<%= product.image.data.toString('base64')%>" alt="">
</article>
<% }) %>
我没试过,但如果 ejs 文件中的代码抛出错误,请尝试将图像以 base64 编码存储在数据库中,然后直接在 ejs 文件中使用 product.image.data