You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>
报错原因
  1. 直接访问新建文章页/articles/new时,对应GET路由的res.render方法没有向模板传递article变量,模板中直接读取article.title等属性时就会触发变量未定义错误。
  2. POST路由中用const声明article变量,后续try块中尝试将保存成功的文档重新赋值给该变量,会触发常量不可重新赋值的类型错误,导致保存逻辑无法正常运行。
修复方案
  1. 修改GET /new路由逻辑,渲染页面时传入一个空的Article实例作为article变量,保证直接访问新建页时模板能拿到合法变量:
router.get('/new', (req, res) => {
  res.render('articles/new', { article: new Article() })
});
  1. 修改POST路由中的变量声明,将const改为let,允许后续对article变量重新赋值为保存完成的文档对象。
  2. 调整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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:27:47