本系列目标
ps(本系列文章将引用ToDo List的专案去演示,抱歉稍后补上专案GitHub连结)
multer档案上传(一)将图片存在DB(本篇) multer档案上传(二)将图片存在storagemulter档案上传(三)将图片存在第三方托管这篇文章你将学习到
将图片存放在storage资料夹中,并将图片渲染在EJS上面开始实作
概念
利用multer将图片存在后端storage,取得图片储存的相对路径,最后EJS在 img tag的src路径去引入该图片
优点:
设定存放图片
dest/storage指定图片存入的位置
multer(opt)这个方法的opt接受指定的key value pair物件,其中两个我们会用来指定图片存放位置的就是dest和storage这两个。
dest
dest就是destination(目的地)的简称,它的值要是string来指定存放路径,在之前我已经用express.static(__dirname + '/public')去告诉express我静态档案是放在public资料夹下面,__dirname就是我的env记录着我专案根目录的位置,这样前后组合起来就是一个绝对路径。
var upload = multer({dest: "public/images/uploads"})
storage
storage有分存MemoryStorage或DiskStorage
MemoryStorage: 简单且没有任何选项,会将档案以buffer object的形式存进记忆体中,object的key叫做buffer(注意!这动作可能会耗尽你的记忆体,请斟酌档案的总容量)var storage = multer.memoryStorage()var upload = multer({ storage: storage })
DiskStorage: 有2个客製化的储存选项destinationfilename下面这个例子我们控制了destination(档案存放的位置),若成功则执行cb(客製化的成功讯息, 存放的相对位置)。filename(编辑档名),若成功则执行cb(客製化的成功讯息, 客製化档案名称),ps.这里的file是multer以物件的型别存放档案资讯的地方。
const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'public') }, filename: function (req, file, cb) { cb(null, file.filename: + '-' + Date.now()) } }) const upload = multer({storage: storage})
接下来,我们要修改成能在后端预览图片
一般来说,把图片存在storage后,是无法直接用预览器去预览图片,这样对于管理不是很友善,所以我们可以引用Node原生的方式fs.rename()来让storage中的图片可以被预览。
引入fs()
routes/index.js加入
const fs = require('fs')
在上传图片router.post()里面加入
这里我们透过fs.rename()的方式修改了图片存放的路径,以及成功则执行callback回传成功讯息。
表达式: fs.rename(oldPath, newPath, callback)
第一个参数oldname即是该图的原路径,第二个newPath则是新路径,我们将它指定在一个变数中方便查看,第三个参数即是执行后的callback成功讯息。
let newPath = `public/images/uploads/${req.file.originalname}`fs.rename(req.file.path, newPath, () => { res.json({result: 'image uploaded successful'})})
上传成功,我们检查一下图片在不在
成功,而且可以直接预览图片
我们把图片相对位置imgPath存入DB
在router.post加入imgPath
var imgPath = {image: `/images/uploads/${req.file.originalname}`}MongoClient.connect(url, function(err, db) { if (err) throw err; var dbo = db.db("todolist"); dbo.collection("images").insertOne(imgPath, function(err, res) { if (err) throw err; console.log("1 image inserted"); db.close(); });});
看一下Mongo DB是否有写入成功
现在我们已经可以把图片存放好,并且DB也将图片的相对位置记录和规划,DB只负责记录网址就可以了。减轻不少DB的负担。
在EJS渲染这张图片
在views/index.ejs修改img tag
<img src="<%= doc.image %>"/>
完成
我们打开网址http://localhost:3000/
今日感想
终于可以理解为什么要把图片存在storage的好处,实作下来我发现,其实不一定要把图片存放在本机中,也可以用託管的方式把图片存在第三方的空间,例如AWS有个S3的图片储存空间。
下一篇,我们把图片託管在第三方空间。