【问题标题】:issue with uploading and retriving images to mongoDB using express使用 express 将图像上传和检索到 mongoDB 的问题
【发布时间】:2022-02-23 09:29:44
【问题描述】:

我正在构建一个初学者全栈项目,我正在创建一个网上商店。在这里,我有一个管理路径,我可以将新产品上传到我的 mongoDB 数据库,以便它们显示在商店中。像任何好的网上商店一样,我需要图片来展示我的产品,但我很难为该功能编写代码。我知道有一个叫做 GridFS 的东西,但是我的图像永远不会超过 16 MB,所以我不想让我的解决方案过于复杂。

请参阅我的代码中箭头下方的 cmets,了解我遇到的具体问题

我的产品架构:

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>
<% }) %>

【问题讨论】:

    标签: node.js mongodb image express mongoose


    【解决方案1】:

    您可以使用像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:[&lt;mediatype&gt;][;base64],&lt;data&gt; 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

    【讨论】:

      猜你喜欢
      • 2017-02-14
      • 2020-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-22
      • 2021-02-04
      • 2015-02-28
      相关资源
      最近更新 更多