簡體   English   中英

使用Node,Express和Multer將文件上傳到MongoDB? 我應該使用Multer還是GRIDfs?

[英]Using Node, Express and Multer for Upload a file to MongoDB? What should I use, Multer or GRIDfs?

您好,我在heroku上運行了一個最終項目,使用MongoLab和Multer上傳照片似乎正常,但是幾小時或更短的時間后,照片從頁面上消失了,但留下了img占位符和其他字段,例如名稱或日期區域。

這是Heroku還是Mongolab的問題,還是僅僅是免費帳戶,原因是免費帳戶? 也沒有關系,只要上傳一張照片或十幾張照片仍會消失。

你可以幫幫我嗎? 是否存在亂碼,棘手的代碼行,或者我對Multer或數據庫犯錯的內容? 我已經在Web和Stack-Overflow上進行了深入研究,我發現了一個名為GRIDfs的東西,但我不知道這樣是否可行。 你能告訴我我是否過分嚴謹嗎?

這是我對Multer的代碼:

var express        = require("express"),
    body_parser    = require("body-parser"),
    multer         = require("multer"),
    mongoose       = require("mongoose");

    var app = express();

    //connect my local database to MongoLab database   

    var url = process.env.DATABASE || "mongodb://localhost/black_hat";

    mongoose.connect(url);

混合機配置

var storage = multer.diskStorage({
destination: function(req, file, callback){
    callback(null, "./public/uploads");
},
filename: function(req, file, callback){
    callback(null, Date.now() + file.originalname);
}
  });

var upload = multer({storage : storage}).single("image");

我的POST路線

    app.post("/fotos_videos", isLoggedIn, function(req, res) {
    upload(req, res, function(err) {
        if(err){
            return res.end("Error uploading file");
        }
        // get data from form
        var newName = req.body.name,
            newCover = "/uploads/" + req.file.filename;
        // Packing into an object
        var newCollage = {
            name : newName,
            cover: newCover
        };
        //create new album
        Collage.create(newCollage, function(err, collage) {
            if(err){
                console.log(err);
            } else {
                // console.log(collage);
                res.redirect("/fotos_videos");
            }
        });
    });
});

我上傳圖片的表格

  <div style="width=30%; margin: 30px auto" > <form action="/fotos_videos" method="POST" enctype="multipart/form-data"> <div class="form-group"> <label>Album Name</label> <input type="text" name="name" placeholder="Album Name" class="form-control"> </div> <div class="form-group"> <label>Choose Album Cover</label> <input type="file" name="image" placeholder="image url" class="form-control" required> </div> <div class="form-group"> <button class="btn btn-lg btn-primary btn-block">Upload</button> </div> </form> <a href="/fotos_videos">Back</a> </div> 

最后是我的拼貼模型

var mongoose = require("mongoose");

// Schema 
var collageSchema = new mongoose.Schema({
    name : String,
    cover : String,
    photos: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Photo"
    }] 
});

var Collage = mongoose.model("Collage", collageSchema);

module.exports = Collage;

任何幫助將不勝感激。

我不知道這是否有幫助。 但據我了解,multer是用於從用戶那里獲取數據的東西(例如上傳的圖片)。 它不做持久存儲。 如果要存儲數據(大文件,如圖像),則應使用gridfs-stream

一旦數據來自用戶,您應該創建一個到GridFs的讀取流。

如果要將圖像保存到數據庫,則不應該具有“ dest”屬性。 multer的實現也是錯誤的,也許是因為這是一個古老的問題,以前的api就是這樣。 在這里你應該做什么。

配置您的multer:

const multer = require("multer");
const upload = multer({
  limits: { fileSize: 5000000 },
  fileFilter(req, file, cb) {
    if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) { //allowed file extensions
      return cb(new Error("please upload png,jpeg or jpg"));
    }
    cb(undefined, true);
  }
});

然后創建一個端點。 你已經有這個了

app.post("/fotos_videos", isLoggedIn, function(req, res) {
   upload(req, res, function(err) { 

這種實現是錯誤的。 Upload是一種中間件,如果您想添加身份驗證,則只有經過身份驗證的用戶才能訪問此端點。 因此我們需要調整此端點。

另外,您還需要為上載定義一個架構,以將其保存到數據庫。 假設您創建了一個名為uploads的模型,並對此進行了建模。 我們不需要用貓鼬來驗證它,因為multer已經在處理它。 確保從刪除配置中刪除dest屬性。 因為如果不刪除,multer會將文件保存到文件夾,因此我們的async (req,res){}函數將無法訪問該文件,因此我們無法將其保存到數據庫。

uploads:{type:Buffer} //將其包含在您的上傳模式中

然后在此文件中調用上傳模型。

router.post(
  "/fotos_videos/me/uploads", isLoggedIn,
  upload.single("uploads"),  //uploads is just a random name when u upload from postman, form form-data,put "uploads" in key field
  async (req, res) => {
    req.upload.uploads = req.file.buffer;//i explain down below
    await req.upload.save();
    res.send();
  },
  (err, req, res) => {
    res.status(400).send("error happned");
  }
);

我們不將圖片存儲在文件系統中。 原因是幾乎所有部署平台都需要我們獲取代碼並將其推送到其服務器上的存儲庫中。 因此,每次部署時文件系統都會被擦除,這意味着部署時我們將丟失數據。 因此,我們將在用戶模型中添加一個字段以將二進制數據的圖像存儲在數據庫中,而不是將圖像存儲在文件系統中。

現在是時候從數據庫中獲取我們的圖像了。 為此,您需要一條新路線

router.get("/fotos_videos/:id/uploads", async (req, res) => {
  try {
    const upload = await Uploads.findById(req.params.id);
    if (!upload || !upload.uploads) {
      throw new Error("no image found");
    }
    res.set("Content-Type", "image/png");
    res.send(upload.uploads);
  } catch (e) {
    res.status(400).send(e.message);
  }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM