vue + mavon-editor +axios + node + express + multer 实现图片上传功能

895 阅读3分钟

自己做node后台管理项目碰到编辑器中图片上传功能,网上搜索资源发现不全,搞定后分享一下

首先粘贴出前端后端的正确代码然后在说明使用遇到的BUG

前端代码 我的图片上传是编辑器当中的,但是用于其它上传都可以

编辑器文件 使用的是vue中的makdown编辑器

<template>
    <mavon-editor ref=md v-model="editor.content" @imgAdd="$imgAdd" ></mavon-editor>
</template>
<script>
$imgAdd (pos, file) {
      var that = this
      var formdata = new FormData()
      console.log(pos)
      console.log(file)
      formdata.append('imgFile', file)
      console.log(formdata)
      console.log(formdata.getAll('imgFile'))
      var postData = {
        formdata: formdata
      }
      that.$axios('post', '/upload', formdata).then(res => {
        console.log(res.url)
        that.$refs.md.$img2Url(pos, res.url)
      })
    }
</style>

axios 文件主要配置

axios.defaults.headers.post['Content-Type'] = false
// 封装post请求
function post (url, params) {
  return new Promise((resolve, reject) => {
    // qs.stringify(params)图片上传不可以使用qs
    axios.post(url, params)
      .then(res => {
        resolve(res.data)
      }).catch(err => {
        reject(err.data)
      })
  })
}

export default function request (method, url, params) {
  if (method === 'get') {
    return get(url, params)
  } else if (method === 'post') {
    return post(url, params)
  }
}

说明一下前端所遇到的BUG

第一步就是 headers的设置
axios.defaults.headers.post['Content-Type'] = false;
一开始设置的是
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
但是文件上传的时候看了文档要设置成
headers: { 'Content-Type': 'multipart/form-data' },
使用的时候还是不成功
node的报错为no multipart boundary was found
这个报错的原因是 在请求的时候正常 multipart/form-data 后面会接一个 boundary但是我的请求并没有
所以根据提示我 headers设置为
axios.defaults.headers.post['Content-Type'] = false;
第二部错误是formdata在post请求的时候并没有展示 
formdata 输出数据要是用formdata.getAll()
console.log(formdata.getAll('imgFile'))
查找原因 我的axios post 用Qs.stringify()将对象序列化成URL的形式但是文件上传的时候不需要因此
直接使用params
axios.post(url, params)

node后端所遇到的BUG

第一步跨域错误
我的代码前后端分离了 而且不在一个工程中使用的因此跨域了
一开始我使用的跨域方式为
设置跨域访问
app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By",' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
});
但是因为前端的axios.defaults.headers.post['Content-Type'] = false; 一次请求的时候回报错
因此我换成了node cors 跨域
cnpm install cors --save 
const cors = require('cors') // 解决跨域
app.use(cors())

第二部文件名获取的错误
报错提示 node multer 报错Unexpected field
upload.single('imgFile') 
single 里面 参数是文件名称 Field name 由表单指定
当我们使用input的上传文件的时候
input  中的name必须和single 里面的参数一致
使用mavon-editor上传图片的时候
formdata.append('imgFile', file)第一个参数的名称和single 里面的参数一致都是代表了fromdatakey值

第三部就是图片的保存然后返给前端
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, uploadFolder);    // 保存的路径,备注:需要自己创建
    },
    filename: function (req, file, cb) {
        // 将保存文件名设置
        cb(null, Date.now()+ '-' +  file.originalname );  
    }
});
此处是封装的函数
需要注意的是设置文件字段名的时候使用 file.originalname 一开始我使用的是file.filename结果保存的都是二进制的文件并不是图片 你可以使用 filename 拼接 文件的类型 但是我直接使用得当是originalname它输出的文件全称
第四部分就是前端获取后端的文件了get请求
app.get('/public/uploads/*', function (req, res) {
    res.sendFile( __dirname + "/" + req.url );
    console.log("Request for " + req.url + " received.");
})

参考链接:multer github.com/expressjs/m…

参考链接:mavonEditor github.com/hinesboy/ma…