Vue前端上传图片存入MongoDB报Cannot read property 'path' of undefined
问题根因
你遇到的Cannot read property 'path' of undefined报错是因为后端req.file为undefined,multer没有接收到前端传递的文件字段,具体是前端提交逻辑存在两个问题:
- 没有手动获取文件输入框选中的文件内容,v-model本身不支持input[type=file]类型
- 提交时直接传递了普通JSON对象,没有使用
multipart/form-data格式的FormData对象提交,不符合后端文件上传的接口要求
前端代码修改方案
1. 模板部分给文件输入框加ref标识,方便获取DOM
<template> <div class="add-rope"> <div class="add-rope-inner"> <form @submit.prevent="handleSubmitForm"> <h1>Add</h1> <!-- 新增ref属性,删除原生form的enctype配置,ajax提交时该配置不生效 --> <input type="file" class="add-rope-input" placeholder="image" name="image" ref="imageInput"> <input type="text" class="add-rope-input" placeholder="Naslov" v-model="ropes.title"> <input type="text" class="add-rope-input" placeholder="Promjer" v-model="ropes.diameter"> <input type="number" class="add-rope-input" placeholder="cijena" v-model="ropes.price"> <input type="number" class="add-rope-input" placeholder="mjerna jedinica" v-model="ropes.cartQuantity"> <input type="text" class="add-rope-input" placeholder="kolicina u skladistu" v-model="ropes.totalQuantity"> <textarea class="add-rope-textarea" placeholder="Opis" v-model="ropes.description"></textarea> <button class="add-rope-button">Dodaj</button> </form> </div> </div> </template>
2. 提交方法改为构造FormData对象提交
<script> import axios from "axios"; import router from "@/router"; export default { data() { return { ropes: { title: '', description: '', diameter: '', price: '', cartQuantity:'', totalQuantity: '' } } }, methods: { async handleSubmitForm() { try { // 1. 获取选中的文件 const imageFile = this.$refs.imageInput.files[0] if (!imageFile) { alert('请先选择商品图片') return } // 2. 构造FormData对象 const formData = new FormData() // 3. 追加文件字段,字段名要和后端upload.single('image')的参数一致 formData.append('image', imageFile) // 4. 追加其他普通字段 Object.keys(this.ropes).forEach(key => { formData.append(key, this.ropes[key]) }) // 5. 提交请求 await axios.post('http://localhost:3000/api/ropes', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) this.$router.push('/crud') this.ropes = { title: '', description: '', diameter: '', price: '', cartQuantity:'', totalQuantity: '' } // 清空文件输入框内容 this.$refs.imageInput.value = '' router.go(-1) } catch (error) { console.log(error) } } } } </script>
后端可选优化(避免空文件提交时报错)
可以先判断req.file是否存在再取值:
router.post('/', upload.single('image'), async (req, res) => { try { if (!req.file) { return res.status(400).send('请上传商品图片') } const rope = new Rope({ title: req.body.title, description: req.body.description, image: req.file.path, diameter: req.body.diameter, price: req.body.price, cartQuantity: req.body.cartQuantity, totalQuantity: req.body.totalQuantity }); await rope.save(); res.status(201).json(rope); } catch (err) { res.status(400).send(err); } });
内容的提问来源于stack exchange,提问作者Josip Marić
相关产品推荐
相关产品推荐

