iT邦幫忙

1

[Node.js]實作multer檔案上傳(一)

本系列目標

ps(本系列文章將引用ToDo List的專案去演示,抱歉稍後補上專案GitHub連結)

這篇文章你將學習到

  • 將圖片存在storage,並且可以預覽以及將圖片渲染在EJS上面

開始實作

安裝multer套件

npm install multer --save

要記得在檔案的最上面引入multer

const multer = require('multer');

這步是預先將圖片存入storage中做好

我們定義storage是存在public資料夾中

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, 'public')
    },
    filename: function (req, file, cb) {
      cb(null, file.fieldname + '-' + Date.now())
    }
  })

然後把剛剛的storage存在變數當作middleware

var upload = multer({storage: storage})

把圖片存進Mongo DB

routes/index.js 加入post method

網路上爬了許多資料發現寫進資料庫之前,必須要先用base64給image編碼才能存入

router.post('/uploadfile', upload.single('myfile'), function(req, res) {
    var img = fs.readFileSync(req.file.path);
    var encode_image = img.toString('base64'); //將圖片做base64編碼
    var finalImg = {
        contentType: req.file.mimetype,
        image:  new Buffer(encode_image, 'base64')
    };
     MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        var dbo = db.db("todolist");
        dbo.collection("Images").insertOne(finalImg, function(err, res) {
          if (err) throw err;
          console.log("1 image inserted");
          db.close();
        });
     });
})

看一下Mongo DB是否有寫入成功

輸入Mongo CLI查看

因為我建立了一個collection叫做images,所以我們先列出images所有的record
打開terminal輸入

$db.images.find()

成功!DB有看到base64的圖片

https://ithelp.ithome.com.tw/upload/images/20200516/20121402J6aWO3ga9x.png

接下來,我們要把圖片從DB取出並由EJS渲染出來

routes/index.js 加入get method

這裡我們注意到,res.render()是把給EJS的資料用string的方式傳過去,傳過去給EJS的時候再由form表單去接收base64編碼的圖片資料。

router.get('/', function(req, res) {
    const findImages = function (db, callback) {
        const collection = db.collection('Images')
        const filename = "5ebb9f6f38d8f18c19b3c7a3"
 
        collection.find({'_id': ObjectId(filename)}).sort({_id: -1}).toArray(function (err, pics) {
            console.log("Find the following records on collection of images")
            callback(pics)
            const data = pics[0]
        
            res.render('index', {  
                userName: "Guest",
                pics: data.image.toString('base64') //注意這裡將圖片decode
            });
        })
    }
    MongoClient.connect(url, function (err, client) {
        const db = client.db(dbName)
        console.log("Connected successfully to server")
        findImages(db, function () {
            client.close()
        })
    })
})

在EJS加入img Tag

views/index.ejs

這裡的src是準備讀取從後端傳送過來base64編碼的PNG圖片。

<img src="data:image/png;base64,<%- pics %>"/> 

完成

我們打開網址http://localhost:3000/

https://ithelp.ithome.com.tw/upload/images/20200516/20121402pZF8Vfy9WC.png

今日感想

其實,將圖片寫進DB並不是很好的方式,會發生以下缺點:

  • 因為base64字串太長,會導致DB查詢速度變慢
  • DB的欄位是有限(如excel一般),可能會導致圖片儲存不完整

下一篇,我們將圖片存入storage裡面,改善以上缺點。


尚未有邦友留言

立即登入留言