实现
第一步,引入依赖
const fs = require('fs')
const multer = require('multer')
第二步,先设置一个上传守卫,用于初步拦截异常请求
/*** 上传守卫* @param req* @param res* @param next*/
function uploadFile (req, res, next) {// dest 值为文件存储的路径;single方法,表示上传单个文件,参数为表单数据对应的keylet upload = multer({dest: 'uploads/'}).single('file')upload(req, res, (err) => {// 获取文件相应数据let file = req.filelet menutype = req.body.type// 判断是否有上传文件if (file !== undefined) {const isJPG = file.mimetype !== undefined ? file.mimetype === 'image/jpeg' | file.mimetype === 'image/png' : falseconst isLt2M = file.size !== undefined ? file.size / 1024 / 1024 < 2 : falseconst filepath = file.filename !== undefined ? './uploads/' + file.filename : ''const fileName = file.originalname !== undefined ? file.originalname : ''// 判断文件处理是否异常if (err) {// 删除临时文件fs.unlinkSync(filepath)user.uploadLog(req, fileName, 'false', '文件类型或大小异常错误,请按提示选择文件', 'upload', err)res.end(JSON.stringify({traceId: req.traceId,code: 301,msg: '文件类型或大小异常错误,请按提示选择文件',data: err}))} else if (!isJPG | !isLt2M) {// 删除临时文件fs.unlinkSync(filepath)user.uploadLog(req, fileName, 'false', '文件类型或大小超过限制,请按提示选择文件', 'upload', '')res.end(JSON.stringify({traceId: req.traceId,code: 302,msg: '文件类型或大小超过限制,请按提示选择文件',data: 'isJPG:' + isJPG + ';isLt2M:' + isLt2M}))} else if (uploadtype.indexOf(menutype) === -1) {// 删除临时文件fs.unlinkSync(filepath)user.uploadLog(req, '', 'false', '上传类型不能为空或者其他', 'upload', '')res.end(JSON.stringify({traceId: req.traceId,code: 308,msg: '请求参数缺失或不正确',data: 'type类型不合法'}))} else {// 执行上传操作next()}}})
}
第三步,写接口,并引用上面的上传守卫
/*** 后端upload上传文件到本地* file 上传的文件* type 上传类型(头像/聊天)*/
router.post('/upload', uploadFile, (req, res) => {let file = req.filelet menutype = req.body.type// 获取文件后缀名,如'.jpg'let index = file.originalname.lastIndexOf('.')let type = file.originalname.substr(index)// 获取当前年月,作为区分子目录let month = moment(Date.now()).format('YYYY-MM')// 随机生成16进制的28位数的文件名,用于上传oss时显示let ossName = Math.random().toString(16).slice(2) + Math.random().toString(16).slice(2)ossName = `${ossName}${type}`// 拼接新文件存储路径(文件目录+随机数+文件后缀名),用于上传oss时显示let osspath = ''if (menutype === 'avatar') {osspath = 'upload/' + month + '/' + ossName} else {osspath = 'chart_upload/' + month + '/' + ossName}// 临时文件在服务器中的本地路径let filePath = './' + req.file.path// 重写文件,生成图片,用于上传fs.rename(filePath, ossName, (err) => {if (err) {res.end(JSON.stringify({traceId: req.traceId,code: 306,msg: '临时文件重写为图片失败',data: err}))} else {// 复制文件到指定目录fs.cp(ossName, 'uploads/' + osspath, (err) => {// 删除原文件fs.unlink(ossName, err => {if (err) {console.log('自动删除上传的源文件失败:' + err)} else {}})if (err) {res.end(JSON.stringify({traceId: req.traceId,code: 307,msg: '图片移动到指定文件夹失败',data: err}))} else {res.end(JSON.stringify({traceId: req.traceId,code: 200,msg: '文件上传成功',data: osspath}))}})}})
})