开始学习node,想开发一个简易版的blog系统,前端用vue,后端使用node,第一次接触后端代码,还是有点不熟悉的。不说没用的了,我想实现blog发表。
1.第一次尝试
把文字和图片提取出来,然后整个markdown数据全部存入数据库
async saveNote (value, render) {
let imgStr = render.match(/<img[^>]+>/g)
let relatedImg = ''
let data = render
let pattern = new RegExp('<p.*?>(.*?)</p>', 'i')
let thumbnailArticle = data.match(pattern)[1]
if (imgStr) {
relatedImg = imgStr[0].match(/src=[\'\"]?([^\'\"]*)[\'\"]?/i)[1]
imgStr.forEach((item, index) => {
if (index === 0) {
thumbnailArticle = data.substring(3, data.indexOf(item))
}
data = data.replace(item, '')
})
}
let res = await resApi.publishBlog(this.userId, this.title, render, relatedImg, thumbnailArticle, utils_.getCurrentTime())
if (res) {
if (res.code === 2000000) {
this.$router.push({name: 'BlogList'})
} else {
this.$Message.error(res.message)
}
}
}
尴尬了,数据太多,导致报错,好吧,我承认我的想法错了。
2.第二次尝试(成功了)
思路:每次添加图片,都先上传至服务器,然后服务器返回url,替换掉当前的url
实现:(使用 vue的markdown库mavoneditor + node.js 中间件Multer)
直接上代码:
vue前端代码(mavonEditor官网:https://github.com/hinesboy/mavonEditor)
<mavon-editor ref="md" v-model="note" @imgAdd="imgAdd" @save="saveNote"/>
methods: {
// 绑定@imgAdd event
async imgAdd (pos, file) {
// 第一步.将图片上传到服务器.
let formdata = new FormData()
formdata.append('imgFile', file)
let res = await resApi.uploadImg(formdata)
// 替换掉当前的url
this.$refs.md.$img2Url(pos, res.url)
}
... ...
}
}
</script>
node代码:(首先安装依赖npm install --save multer)
官网:https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
... ...
var multer = require('multer');
var path = require('path');
var storage = multer.diskStorage({
destination: function (req, file, cb){
cb(null, path.join(__dirname , '../public/resource'));
},
filename: function (req, file, cb){
cb(null, file.originalname);
}
});
var upload = multer({
storage: storage
}).single('imgFile');
// upload image
router.post('/upload_images', function (req, res) {
upload(req, res, function (err) {
console.log('-----------------开始上传------------------');
if (err) {
console.log(err);
res.writeHead(404);
res.end(err.message);
return
}
let url = 'http://' + req.headers.host + '/resource/' + req.file.originalname
res.writeHead(200);
res.end(JSON.stringify({'url': url}));
console.log('-----------------上传完成------------------');
console.log('-----------------文件信息: ');
console.log(req.file ? req.file : '文件错误');
})
})
... ...
说实话官网给的还是非常详细的,其中的具体内容,直接参考官网即可。
3. 问题
在使用mavonEditor+ multer的过程中,node后端获取不到req.file(当然多文件上传的话是req.files),一直报错undefined。
下面说一说问题:
①Multer 是一个 node.js 中间件,用于处理 multipart/form-data
类型的表单数据,它主要用于上传文件。它是写在 busboy 之上非常高效。所以在请求头部也就是headers里就不需要加任何配置了,不然会报错。
②也是我遇到的问题,请求参数是一个formData数据,所以不要转换成其他类型了,我是傻傻的认为post就应该传json,习惯的转化了,废了半天,才找到问题
我用的axios,配置信息
imgPost (url, data) {
return axios({
method: 'post',
baseURL: global_.httpUrl,
url,
data: data,
timeout: 10000
}).then(
(response) => {
return checkStatus(response)
}
).then(
(res) => {
return checkCode(res)
}
)
},
import http from '../config/http'
/**
* 上传图片
*/
export const uploadImg = (image) => http.imgPost('/upload_images', image)
③参数格式肯定是如下格式
------WebKitFormBoundaryBuTNuRtKe9qDYREO
Content-Disposition: form-data; name="imgFile"; filename="1.png"
Content-Type: image/png
------WebKitFormBoundaryBuTNuRtKe9qDYREO--
④文件名一定要匹配
formdata.append('imgFile', file) // imgFile 就是我定义的文件名
后端(node)也一定是 imgFile,一定要和你前端定义的相同
var upload = multer({
storage: storage
}).single('imgFile');
目前遇到的就是这些问题,一些其他的问题等遇到我会在总结,希望有所帮助。