前段时间用Node.js: express + MySQL + Vue + element组件做了一个小项目,记录一下图片上传的实现。
将图片存入数据库有两种方法:
1,将图片以二进制流的方式存入数据库(数据库搬家容易,比较安全,但数据库空间的消耗大,访问会比较缓慢)
2,将图片的存放地址存入数据库
主要介绍第二种。
将图片转成base64格式,数据类型使用MEDIUMTEXT类型。
或者将图片转为保存到数据库的Blob类型中。
会运用到一个中间件,Multer,用于处理 multipart/form-data
类型的表单数据,它主要用于上传文件 :multer/README-zh-cn.md at master · expressjs/multer · GitHub
Multer会添加一个body对象以及file或files对象到request对象中,body对象包含表单的文本域信息,file对象包含对象表单上传的文件信息。
(router和router_handle两个文件夹的意思是,将路径和执行方法分开,方便管理,具体内容可以查看 Node.js: express + MySQL的使用_express mysql_掉头发类型的选手的博客-CSDN博客)
router下的文件
//引入multer
const multer = require('multer')
//磁盘存储引擎,可以控制文件的存储,省略的话这些文件会保存在内存中,不会写入磁盘
const storage = multer.diskStorage({
destination: function (req, file, cb) {
//控制文件的存储路径
cb(null, 'image/avatar')
},
filename: function (req, file, cb) {
//定义上传文件存储时的文件名
cb(null, file.originalname)
}
})
const upload = multer({ storage: storage })
//接受单文件上传
router.post('/update/avatar', upload.single('avatar'), userInfo_handler.updateAvatar)
首先引入multer,配置图片的存储地址和文件名,省略的话上传的文件会保存在内存中,不会写入磁盘,在上传前要在项目的根目录下创建一个文件夹用于接收上传的文件,比如,我的代码中定义文件的存储路径为 cb(null, 'image/avatar') ,要在目录下创建一个image文件夹,再在image文件夹下创建一个avatar文件夹。
定义文件存储时的文件名一般会使用时间戳作为文件名,防止上传的文件重复(我这儿没有使用时间戳)。
upload.single('avatar') 表示接受单文件上传,avatar代表上传文件时的参数字段。多文件上传使用 .array(fieldname[, maxCount])
,maxCount来限制最大的上传数量。
router_handler文件下的处理函数
exports.updateAvatar = (req, res) => {
// 定义更新头像的sql
const sql = 'update users set avatar=? where id=?;'
// console.log(req);
// console.log(req.body.id)
// console.log(req.file);
// console.log(req.file.destination);
const avatarUrl = `http://127.0.0.1:3007/${req.file.destination.split('/')[1]}/${req.file.originalname}`
// console.log(avatarUrl);
// 执行sql语句
db.query(sql, [avatarUrl, req.body.id], (err, results) => {
// sql语句执行错误
if(err) return res.cc(err)
// sql语句执行成功,但影响的条数部位1属于执行失败
if(results.affectedRows !== 1) return res.cc('更换头像失败!')
// 更换头像成功
res.cc('更换头像成功!', 0)
})
}
传回的request
这时使用 req.file取到上传的图片信息,req.body取到其他上传的数据。
然后处理图片路径,图片路径根据自己项目的实际情况进行处理。最后执行sql语句,存入数据库。
接口处理完毕。
要想在浏览器中通过路径访问图片还需要在 app.js 这个文件中加入
app.use(express.static('image'))
将整个image文件夹转为静态文件。
前端代码用element组件举个例子。使用element中上传的组件。其中有几个属性是比较重要的。
action 是请求的URL,如果你写的接口需要上送token,需要配置headers,data是请求中除了图片文件其他的额外参数,name是上传图片文件的字段,这个字段必须和定义url时的那个字段保持一致,就是下面这个字段。
之后再重新请求数据库中的数据,将图片显示在页面上。
上传之后
图片的保存位置
数据库中
这个路径可以直接在浏览器中访问