文件上传报错TypeError: Cannot read path of undefined,求排查原因
我来帮你分析这个问题,你遇到的TypeError: Cannot read path of undefined本质是后端的req.file为undefined,说明前端没有成功把文件数据传递到后端。咱们一步步拆解问题:
1. 前端jQuery代码的低级错误
你的表单提交事件里,参数是e,但你写了event.preventDefault()——这里event是未定义的,会直接导致代码报错中断,表单会走默认提交流程,而不是你写的AJAX上传逻辑,这大概率是文件没传过去的核心原因之一。
修复方法:把event.preventDefault()改成e.preventDefault():
$('#frm-chat').submit(function (e) { e.preventDefault() // 修正参数为e let file = $('#file').val() console.log(file) $.ajax({ url: "/send-message", type: "POST", data: new FormData(this), processData: false, contentType: false, }).always(function (response) { if (response.status == 'error') { console.log("error") } console.log("success") }) })
2. span嵌套input的交互问题
你提到移除span后上传功能失效,说明你的span应该是用来实现“仅显示图标”的样式容器——通常这种场景会把原生file input设为透明或隐藏,通过点击span来触发文件选择。但默认情况下,点击span不会自动触发内部input的点击事件,导致你看似点击了图标,实际上并没有打开文件选择框,自然没有文件被选中,后端就拿不到req.file。
解决这个问题,你需要给span添加点击事件,手动触发input的点击:
// 给图标容器添加点击事件,触发文件选择 $('.attachment').click(function() { $('#file').click() })
同时,确保你的CSS正确隐藏原生input,只显示span的图标(示例样式):
#file { position: absolute; opacity: 0; width: 0; height: 0; overflow: hidden; } .attachment { cursor: pointer; /* 给图标添加点击光标提示 */ /* 可以根据需要调整图标大小、颜色等样式 */ }
3. 验证FormData是否正确包含文件
可以在AJAX发送前,打印FormData里的文件对象,确认是否有数据:
$('#frm-chat').submit(function (e) { e.preventDefault() let formData = new FormData(this) console.log(formData.get('file')) // 如果输出File对象说明正常,否则就是没选中文件 $.ajax({ // ... 原有AJAX配置 }) })
4. 后端multer中间件的配置检查
你用了upload.single('file'),要确保multer的配置是正确的,比如要指定有效的存储目录(且目录必须存在):
const multer = require('multer') const path = require('path') // 配置multer的存储路径 const storage = multer.diskStorage({ destination: function (req, file, cb) { // 确保public/uploads目录存在,不存在的话要手动创建或用代码生成 const uploadDir = path.join(__dirname, 'public/uploads') cb(null, uploadDir) }, filename: function (req, file, cb) { // 生成唯一文件名避免冲突 cb(null, Date.now() + '-' + file.originalname) } }) const upload = multer({ storage: storage })
如果multer的存储目录不存在,会导致文件无法保存,进而req.file为undefined。
总结一下:先修复event参数的错误,再确保span能正确触发input的点击事件,这样应该就能解决req.file为undefined的问题,也就不会出现读取path的错误了。
内容的提问来源于stack exchange,提问作者July333

