如何在NodeJS/Express+EJS表单中传递项目ID至带参POST路由
问题
我正在用NodeJS/Express搭配EJS构建表单对接API路由,但没法把带项目ID的POST路由和EJS表单关联起来。请问怎么在EJS里添加这个ID,实现表单和指定POST路由对接并获取表单数据?
我的POST路由代码
router.post('/:id/new', upload.single('file'), async (req, res) => { // 这里我想把项目ID加到URL里 //const project = await Project.findById(req.params.id) const releasenoteData = { user : await req.user._id, title: req.body.title, path: req.file.path, originalName: req.file.originalname, description: req.body.description, createdAt: req.body.createdAt, } try { const releasenote = await ReleaseNote.create(releasenoteData) console.log(releasenote) res.redirect('/') } catch { if (releasenoteData.path != null) { res.redirect('/new', { errorMessage: 'Error Creating the Release Note' }) } } })
我的EJS表单代码
<form action="/new" method="POST" enctype="multipart/form-data"> // 我觉得这里应该在new前面加ID <label for="text">Title: </label> <input type="text" id="title" name="title"> <br><br> <label for="file">File: </label> <input type="file" id="file" name="file" required> <br><br> <label for="text">Description: </label> <input type="text" id="description" name="description"> <br><br> <label for="date">Upload Date: </label> <input type="date" id="createdAt" name="createdAt"> <br><br> <button type="submit">Add Release Note</button> </form>
解决方案
核心是让EJS动态生成包含项目ID的表单提交路径,同时完善后端逻辑确保ID能正确关联数据。
1. 渲染表单页时传入项目ID
先在渲染表单的GET路由里,把目标项目的ID传递给EJS模板:
router.get('/projects/:id/new-releasenote', async (req, res) => { const projectId = req.params.id; // 可选:如果需要展示项目信息,可查询后一起传递 // const project = await Project.findById(projectId); res.render('your-form-template', { projectId }); });
2. 修改EJS表单的action属性
在EJS模板里,用动态变量替换固定路径,把项目ID插入到提交地址中:
<form action="/<%= projectId %>/new" method="POST" enctype="multipart/form-data"> <label for="title">Title: </label> <input type="text" id="title" name="title"> <br><br> <label for="file">File: </label> <input type="file" id="file" name="file" required> <br><br> <label for="description">Description: </label> <input type="text" id="description" name="description"> <br><br> <label for="createdAt">Upload Date: </label> <input type="date" id="createdAt" name="createdAt"> <br><br> <button type="submit">Add Release Note</button> </form>
这样表单提交时,就会请求/项目ID/new这个带参数的路由,后端就能通过req.params.id拿到项目ID。
3. 完善后端逻辑(可选但建议)
取消路由里的注释,把项目ID关联到发布记录中,同时优化错误处理:
router.post('/:id/new', upload.single('file'), async (req, res) => { const project = await Project.findById(req.params.id); // 校验项目是否存在 if (!project) { return res.redirect('/'); } const releasenoteData = { user: req.user._id, // 这里不需要await,req.user._id是直接可用的ObjectId project: project._id, // 关联项目ID title: req.body.title, path: req.file.path, originalName: req.file.originalname, description: req.body.description, createdAt: req.body.createdAt || new Date(), // 前端没传的话用当前时间 } try { const releasenote = await ReleaseNote.create(releasenoteData) console.log(releasenote) // 可以重定向到项目详情页,体验更好 res.redirect(`/projects/${project._id}`) } catch (err) { console.error(err); // 打印错误方便调试 // 清理已上传的文件,避免垃圾数据 if (req.file?.path) { const fs = require('fs'); fs.unlinkSync(req.file.path); } // 渲染回表单页并提示错误,保留用户已填内容 res.render('your-form-template', { projectId: req.params.id, errorMessage: '创建发布记录失败,请重试' }); } })
内容的提问来源于stack exchange,提问作者User101
相关产品推荐
相关产品推荐

