Node.js文件上传:如何替换图片展示为显示文件名(MongoDB+Multer)
解决文件上传后图片/非图片差异化展示问题
问题描述
我是一名正在学习使用Node.js和MongoDB实现文件上传功能的初学者。按照教程操作后,上传的文件会以图片形式展示,但上传非图片类文件(如PDF)时会显示空白图片框。我希望将展示形式改为显示文件名(例如上传PDF时显示beginning_tutorial.pdf),以便明确上传的文件内容。目前我使用multer处理文件上传,但不知道如何修改代码实现该需求,恳请各位开发者提供指导,帮助我理解具体的实现方法,非常感谢。
我的依赖包版本:
"body-parser": "^1.20.1", "ejs": "^3.1.8", "express": "^4.18.2", "fs": "^0.0.1-security", "mongoose": "^6.8.1", "multer": "^1.4.5-lts.1"
解决方案
核心思路
在数据库中额外存储文件名(或MIME类型),在视图层根据文件类型判断:图片文件显示预览图,非图片文件显示原始文件名。
步骤1:更新MongoDB Schema,添加文件名字段
打开app.js,修改fileSchema,新增filename字段用于存储原始文件名:
const fileSchema = new mongoose.Schema({ filespath: String, filename: String // 新增:存储上传文件的原始名称 })
步骤2:修改上传逻辑,保存文件名到数据库
更新app.post('/')接口,将req.file.originalname(multer提供的原始文件名)存入数据库:
app.post('/',upload.single('file'),(req,res)=>{ const x= 'uploads/'+req.file.originalname; const files = new fileModel({ filespath:x, filename: req.file.originalname // 新增:保存原始文件名 }) files.save((err,data)=>{ if(err){ console.log(err) } else{ console.log('data',data) res.redirect('/') } }) })
步骤3:修改EJS视图,实现差异化展示
打开home.ejs,修正循环条件并添加文件类型判断逻辑:
<tbody> <% // 定义常见图片扩展名集合 const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']; // 修正原循环条件的错误 for(var i=0; i < data.length; i++) { // 获取文件扩展名并转为小写 const fileExt = data[i].filename.split('.').pop().toLowerCase(); %> <tr> <td> <% if(imageExts.includes(fileExt)) { %> <!-- 图片文件:显示预览图 --> <img src="<%= data[i].filespath %>" style="width:100px; height:100px;"> <% } else { %> <!-- 非图片文件:显示原始文件名 --> <span style="line-height:100px;"><%= data[i].filename %></span> <% } %> </td> <td> <form action="/download/<%= data[i]._id %>" method="GET"> <input type="submit" value="Download"> </form> <form action="/delete/<%= data[i]._id %>" method="GET"> <input type="submit" value="Delete"> </form> </td> </tr> <% } %> </tbody>
可选优化:用MIME类型判断文件类型(更准确)
如果需要更精准的文件类型判断,可以利用multer提供的req.file.mimetype:
- 更新Schema添加MIME类型字段:
const fileSchema = new mongoose.Schema({ filespath: String, filename: String, mimetype: String // 新增:存储文件的MIME类型 })
- 上传时保存MIME类型:
const files = new fileModel({ filespath:x, filename: req.file.originalname, mimetype: req.file.mimetype // 新增:保存MIME类型 })
- 视图层判断逻辑修改为:
<% if(data[i].mimetype.startsWith('image/')) { %> <img src="<%= data[i].filespath %>" style="width:100px; height:100px;"> <% } else { %> <span style="line-height:100px;"><%= data[i].filename %></span> <% } %>
这种方式不受文件扩展名篡改的影响,判断更准确。
内容的提问来源于stack exchange,提问作者Linserd Tofu
相关产品推荐
相关产品推荐

