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

Express表单提交报错:无法读取undefined的location属性

问题根因

抛出Cannot read properties of undefined (reading 'location')错误的核心原因是路由处理函数参数顺序写反,同时代码存在中间件顺序错误、SQL语法错误、响应逻辑提前执行等问题,按以下方法逐一修复即可正常接收表单数据并存入数据库。

修复步骤
  • 修正路由回调参数顺序
    Express路由处理函数的参数顺序固定为(请求对象req, 响应对象res, 下一步回调next),你在/addNewHouse POST路由、/homes-list GET路由中都把req和res的位置写反,导致代码中访问的req.body实际是响应对象res的属性,res对象不存在body字段,值为undefined,读取location属性时直接触发报错。
    错误写法:

    // /homes-list路由
    router.get('/homes-list', (res,req) => {
    // /addNewHouse路由
    router.post('/addNewHouse', ensureLoggedIn ,(res,req , next) => {
    

    修复为:

    // /homes-list路由
    router.get('/homes-list', (req, res) => {
    // /addNewHouse路由
    router.post('/addNewHouse', ensureLoggedIn ,(req, res, next) => {
    
  • 调整中间件加载顺序
    csurf中间件依赖cookie解析、请求体解析才能正常工作,你当前把csrf中间件放在了解析类中间件前面,会导致csrf校验失败、请求体无法正常解析,调整为以下顺序:

    // 先解析cookie
    app.use(cookieParser());
    // 再解析各类请求体
    app.use(express.json());
    app.use(express.urlencoded({ extended: false }));
    // 最后加载csrf中间件、生成csrf token
    app.use(csrf());
    app.use(function(req, res, next) {
      const token = req.csrfToken();
      res.locals.csrfToken = token;
      next();
    });
    
  • 修正插入数据的SQL逻辑
    原插入逻辑有三个问题:一是SQL插入关键字拼写错误,标准SQL写法是VALUES不是VALUE;二是for是SQL保留关键字,用作列名必须用反引号转义;三是你在数据库异步操作完成前就执行了响应渲染和next回调,会导致未等数据写入完成就返回结果,同时错误处理存在笔误。
    错误写法:

    db.run('INSERT INTO home (owner_id,Location,for) VALUE( ? , ? , ? )',[
      owner,
      req.body.location,
      req.body.for
    ],
    (err) => {
      if (err) { return console.error(err.message.at)}
    }),
    res.render('index');
    next();
    

    修复为:

    const owner = req.user.id; // 不要写死owner=5,登录后直接取当前登录用户id即可
    db.run('INSERT INTO home (owner_id, Location, `for`) VALUES (?, ?, ?)',[
      owner,
      req.body.location,
      req.body.for
    ],
    (err) => {
      if (err) { 
        console.error(err.message);
        return next(err);
      }
      // 数据库写入完成后再跳转,避免重复提交表单
      res.redirect('/');
    });
    
  • 修正其他笔误

    1. fetchTodos函数中的查询SQL只有1个占位符,但传入了2个参数,删掉多余的req.user.first_name即可:
      db.all('SELECT rowid AS id, * FROM houses WHERE owner_id = ?', [
        req.user.id
      ], function(err, rows) {
        // 原有逻辑不变
      })
      
    2. /homes-list路由中res.render("index/#house-list")写法错误,ejs无法直接渲染页面锚点,查询完成后直接跳转到带锚点的首页即可:
      res.redirect('/#house-list');
      

所有修改完成后重启Express服务,即可正常提交表单数据写入数据库。

内容的提问来源于stack exchange,提问作者Ahmed S.Onour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:18:26