Express+EJS实现表单默认值回显报article未定义如何解决?
问题描述
使用Express、MongoDB、EJS模板引擎开发博客系统时,开发新增文章表单提交功能,要求表单校验不通过跳转回新建文章页时,保留用户已填写的输入内容。在表单模板添加回填代码后,页面抛出article is not defined错误,判断为数据未成功传递到前端页面。
相关代码
路由文件 article.js
const express = require('express'); const Article = require('./../models/article') const router = express.Router(); module.exports = router router.get('/new', (req, res) => { res.render('articles/new') }); router.get('/:id', (req, res) => { }); router.post('/', async (req, res) => { const article = new Article({ title: req.body.title, description: req.body.description, markdown: req.body.markdown }); try { article = await article.save() res.redirect(`/articles/${article.id}`); } catch (e) { res.render('articles/new', { article: article }) } });
新建文章页模板 new.ejs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Blog</title> </head> <body> <div class="container"> <h1 class="mb-4">New Article</h1> <form action="/articles" method="POST"> <%- include('_form_fields') %> </form> </div> </body> </html>
表单公共片段 _form_fields.ejs
<div class="form-group"> <label for="title">Title</label> <input required value="<%= article.title %>" type="text" name="title" id="title" class="form-control"> </div> <div class="form-group"> <label for="description">Description</label> <textarea name="description" id="description" class="form-control"><%= article.description %></textarea> </div> <div class="form-group"> <label for="markdown">Markdown</label> <textarea required name="markdown" id="markdown" class="form-control"><%= article.markdown %></textarea> </div> <a href="/" class="btn btn-secondary">Cancel</a> <button type="submit" class="btn btn-primary">Save</button>
报错原因
- 直接访问新建文章页
/articles/new时,对应GET路由的res.render方法没有向模板传递article变量,模板中直接读取article.title等属性时就会触发变量未定义错误。 - POST路由中用
const声明article变量,后续try块中尝试将保存成功的文档重新赋值给该变量,会触发常量不可重新赋值的类型错误,导致保存逻辑无法正常运行。
修复方案
- 修改GET /new路由逻辑,渲染页面时传入一个空的Article实例作为
article变量,保证直接访问新建页时模板能拿到合法变量:
router.get('/new', (req, res) => { res.render('articles/new', { article: new Article() }) });
- 修改POST路由中的变量声明,将
const改为let,允许后续对article变量重新赋值为保存完成的文档对象。 - 调整
module.exports位置到文件末尾,符合常规编码习惯(原有写法不影响运行,因为导出的是router对象引用,后续挂载路由依然生效)。
修复后的完整article.js代码如下:
const express = require('express'); const Article = require('./../models/article') const router = express.Router(); router.get('/new', (req, res) => { res.render('articles/new', { article: new Article() }) }); router.get('/:id', (req, res) => { // 后续补充文章详情页逻辑 }); router.post('/', async (req, res) => { let article = new Article({ title: req.body.title, description: req.body.description, markdown: req.body.markdown }); try { article = await article.save() res.redirect(`/articles/${article.id}`); } catch (e) { res.render('articles/new', { article: article }) } }); module.exports = router
修改完成后,直接访问新建文章页不会再报变量未定义错误,表单提交校验失败时也能正常回填用户已输入的内容。
内容的提问来源于stack exchange,提问作者SKYZE
相关产品推荐
相关产品推荐

