multer前后端实现单文件图片上传

853 阅读3分钟

1.简介

Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。

注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据

Multer 会添加一个 body 对象 以及 filefiles 对象 到 express 的 request 对象中。 body 对象包含表单的文本域信息,filefiles 对象包含对象表单上传的文件信息。

2.前端部分

假设有一表单数据,其中包含所需要的图片文件

uploader:[]为文件

good: {
        good_id: "",
        good_name: "",
        good_num: "",
        good_color: "",
        good_size: "",
        good_prince: "",
        good_time: "",
        uploader: [],      //该数组中存放文件
        supplier_name: "",
        supplier_phone: "",
        good_message: '',
      },

在提交表单的方法中使用new FormData()把form中所有表单元素的name与value组装成一个queryString,其中文件保存在数组中

实例

async onSubmit() {
      let form = new FormData()
      for (const key in this.good) {
        if (Object.hasOwnProperty.call(this.good, key)) {
          if(this.good.uploader.length !== 0 && key ==='uploader'){
            form.append(key,this.good[key][0].file)
          }else{
            form.append(key,this.good[key])
          }
          
        }
      }
      const result = await insertruku(form)
      console.log(result.data)
      }

2.node.js服务器部分

storage

磁盘存储引擎 (DiskStorage)

磁盘存储引擎可以让你控制文件的存储。 有两个选项可用,destinationfilename。他们都是用来确定文件存储位置的函数。

destination 是用来确定上传的文件应该存储在哪个文件夹中。也可以提供一个 string (例如 '/tmp/uploads')。如果没有设置 destination,则使用操作系统默认的临时文件夹。

注意: 如果你提供的 destination 是一个函数,你需要负责创建文件夹。当提供一个字符串,multer 将确保这个文件夹是你创建的。

filename 用于确定文件夹中的文件名的确定。 如果没有设置 filename,每个文件将设置为一个随机文件名,并且是没有扩展名的。

注意: Multer 不会为你添加任何扩展名,你的程序应该返回一个完整的文件名。

每个函数都传递了请求对象 (req) 和一些关于这个文件的信息 (file),有助于你的决定。

注意 req.body 可能还没有完全填充,这取决于向客户端发送字段和文件到服务器的顺序。

下载相关包

npm install --save multer

实例

// 引入处理 multipart/form-data 类型的表单数据的插件
const multer = require('multer')
var path = require('path')

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, path.join(__dirname , '../public/images'))
    },
    filename: function (req, file, cb) {
        console.log(req.body)
        cb(null, Date.now()+file.originalname)
    }
})
const upload = multer({ storage: storage })


// 向ruku表中添加数据
// req.file 是 `uploader` 文件的信息
// req.body 将具有文本域数据,如果存在的话
router.post('/saveku', upload.single('uploader'), (err,results)=>{
    console.log(req.file)
    console.log(req.body)
    if (err) return res.send(err.message)
    res.send("处理成功")
})

错误处理机制

错误处理机制

当遇到一个错误,multer 将会把错误发送给 express。你可以使用一个比较好的错误展示页 (express标准方式)。

如果你想捕捉 multer 发出的错误,你可以自己调用中间件程序。如果你想捕捉 Multer 错误,你可以使用 multer 对象下的 MulterError 类 (即 err instanceof multer.MulterError)。

const multer = require('multer')
const upload = multer().single('avatar')

app.post('/profile', function (req, res) {
  upload(req, res, function (err) {
    if (err instanceof multer.MulterError) {
      // 发生错误
    } else if (err) {
      // 发生错误
    }

    // 一切都好
  })
})

注意:

使用过程中的疑问:文件存储过程中使用filename对文件进行重命名时,如果同一个js文件中使用了两次文件上传且重命名的文件名中使用了表单的文本域信息,即req.body中的信息,会出现第二次使用使用文件上传的表单中的文本域信息为undefined (未搞懂原因,有知道的评论哈~~~~)

如:

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, path.join(__dirname , '../public/images'))
    },
    filename: function (req, file, cb) {
        cb(null, `${req.body.good_name}+${req.body.good_color}+${req.body.good_size}.png`)
    }
})
const upload = multer({ storage: storage })
//${req.body.good_name}、${req.body.good_color}、${req.body.good_size}可以读取到值


const storage2 = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, path.join(__dirname , '../public/images'))
    },
    filename: function (req, file, cb) {
        cb(null, `${req.body.username}+${req.body.sex}.png`)
    }
})
const upload2 = multer({ storage: storage2 })
//${req.body.username}、${req.body.sex}读取的值是undefined