官方介绍:
Multer 是一个 node.js 中间件,用于处理 multipart/form-data
类型的表单数据,它主要用于上传文件。它是写在 busboy 之上非常高效。
中文官方网址:
multer/README-zh-cn.md at master · expressjs/multer · GitHub
怎么使用就不介绍了,官方文档很详细
前端代码:
<input type="file" ref="file1" @change="fileChange1"/>
自己封装的向后端发送请求的函数:
- // 导入自己封装的axios请求实例
- import request from '../tools/request'
- export const addArticle = data => {
- return request({
- method: 'post',
- url: '/my/addActicle',
- // url: '/my/addActicle2',
- // url: '/my/addActicle3',
- headers: {
- 'Content-Type': 'multipart/form-data'
- },
- data
- })
- }
vue代码:
- <script>
- //导入自己向后端发送请求的函数
- import { addArticle } from '../../request/article'
- export default {
- data() {
- return {
- article: {
- title: '文章标题',
- cate_id: 1,
- content: '这是文章内容测试',
- state: '草稿'
- }
- }
- },
- methods: {
- async fileChange1() {
- //读取文件对象,并基于文件对象获取blob数据
- const file = this.$refs.file1.files[0]
- //为对象添加cover_img属性用来保存文件
- this.article.cover_img = file
- //向后端发送请求
- await addArticle(this.article)
- }
- }
- }
- script>
浏览器查看自己的发送参数:
后端路由代码:
- const multer = require('multer')
- //创建multer的实例对象,通过dest属性指定文件的存放路径
- const upload = multer({ dest: path.join(__dirname, '../uploads') })
- //'cover_img'为前端存储文件的属性名,必须一致
- router.post('/addActicle', upload.single('cover_img'), addActicle)
自己封装的将后端接收到文件保存文件夹中:
- //文章路由处理函数
- const fs = require('fs')
- const path = require('path')
- function saveImg(file, sign) {
- return new Promise((resolve, reject) => {
- fs.readFile(file.path, async (err, data) => {
- if (err) {
- reject(err)
- }
- // 拓展名
- let extName = file.mimetype.split('/')[1]
- // 拼接成图片名
- // 这里可以自行修改
- let imgName = `${sign}-${Date.now()}.${extName}`
- // 写入图片
- // 写入自己想要存入的地址
- await fs.writeFile(path.join(__dirname, `../upload/${imgName}`), data, err => {
- //写入失败
- if (err) { reject(err) }
- //写入成功,同时返回需要存储在数据中的相对路径
- resolve(`/upload/${imgName}`)
- })
- // 删除二进制文件
- await fs.unlink(file.path, err => {
- if (err) { reject(err) }
- })
- })
- })
- }
后端路由处理函数代码:
- exports.addActicle = (req, res) => {
- // console.log(req.body);//文本类型的数据
- // console.log(req.file);//文件类型的数据
- let file = req.file
- console.log('通过multer解析文件信息对象', file);
- saveImg(file, req.user.username).then(res => {
- // res就是我返回的相对地址的位置
- console.log(res);
- }).catch(err => {
- // 啊....啊 最苦恼的bug环节
- console.log(err);
- })
- }
后端接收成功:
第一种方式
前端代码:
<input type="file" ref="file1" @change="fileChange1" multiple />
自己封装的向后端发送请求的函数:
- // 导入自己封装的axios请求实例
- import request from '../tools/request'
- export const addArticle = data => {
- return request({
- method: 'post',
- //url: '/my/addActicle',
- url: '/my/addActicle2',
- // url: '/my/addActicle3',
- headers: {
- 'Content-Type': 'multipart/form-data'
- },
- data
- })
- }
vue代码:
- <script>
- import { addArticle } from '../../request/article'
- export default {
- data() {
- return {
-
- }
- },
- methods: {
- async fileChange1() {
- //读取文件对象,并基于文件对象获取blob数据
- const files = this.$refs.file1.files
- const form = new FormData()
- for (const item of files) {
- form.append('cover_img', item)
- }
- form.append('test', 1)
- await addArticle(form)
- }
- }
- }
- script>
浏览器查看自己的发送参数:
后端路由代码:
- const multer = require('multer')
- //创建multer的实例对象,通过dest属性指定文件的存放路径
- const upload = multer({ dest: path.join(__dirname, '../uploads') })
- //'cover_img'为前端存储文件的属性名,必须一致
- router.post('/addActicle2', upload.array('cover_img', 3), addActicle2)
后端路由处理函数代码:
- exports.addActicle2 = (req, res) => {
- // console.log('通过token解析出来的用户信息对象', req.user);
- console.log('通过multer解析表单的文本类型数据', req.body);
- let files = req.files
- console.log('通过multer解析表单的文件类型数据', files);
- }
后端接收成功:
第二种方式
前端代码:
- <input type="file" ref="file1" @change="fileChange1" multiple />
- <input type="file" ref="file2" @change="fileChange2" multiple />
- <button @click="addArticle">上传</button>
自己封装的向后端发送请求的函数:
- // 导入自己封装的axios请求实例
- import request from '../tools/request'
- export const addArticle = data => {
- return request({
- method: 'post',
- //url: '/my/addActicle',
- //url: '/my/addActicle2',
- url: '/my/addActicle3',
- headers: {
- 'Content-Type': 'multipart/form-data'
- },
- data
- })
- }
vue代码:
- <script>
- import { addArticle } from '../../request/article'
- export default {
- data() {
- return {
- form: new FormData()
- }
- },
- methods: {
- async fileChange1() {
- //读取文件对象,并基于文件对象获取blob数据
- const file = this.$refs.file1.files[0]
- this.form.append('cover_img', file)
- this.form.append('test', 1)
- },
- async fileChange2() {
- const file = this.$refs.file2.files[0]
- this.form.append('avatar', file)
- },
- async addArticle() {
- await addArticle(this.form)
- }
- }
- }
- script>>
浏览器查看自己的发送参数:
后端路由代码:
- const multer = require('multer')
- //创建multer的实例对象,通过dest属性指定文件的存放路径
- const upload = multer({ dest: path.join(__dirname, '../uploads') })
- router.post('/addActicle3', upload.fields([{ name: 'cover_img', maxCount: 3 }, { name: 'avatar', maxCount: 2 }]), addActicle3)
后端路由处理函数代码:
- exports.addActicle3 = (req, res) => {
- console.log('通过token解析出来的用户信息对象', req.user);
- console.log('通过multer解析表单的文本类型数据', req.body);
- let files = req.files
- console.log('通过multer解析表单的文件类型数据', files);
- }
后端接收成功: