Express表单提交报错:无法读取undefined的location属性
问题根因
抛出Cannot read properties of undefined (reading 'location')错误的核心原因是路由处理函数参数顺序写反,同时代码存在中间件顺序错误、SQL语法错误、响应逻辑提前执行等问题,按以下方法逐一修复即可正常接收表单数据并存入数据库。
修复步骤
修正路由回调参数顺序
Express路由处理函数的参数顺序固定为(请求对象req, 响应对象res, 下一步回调next),你在/addNewHousePOST路由、/homes-listGET路由中都把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('/'); });修正其他笔误
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) { // 原有逻辑不变 })/homes-list路由中res.render("index/#house-list")写法错误,ejs无法直接渲染页面锚点,查询完成后直接跳转到带锚点的首页即可:res.redirect('/#house-list');
所有修改完成后重启Express服务,即可正常提交表单数据写入数据库。
内容的提问来源于stack exchange,提问作者Ahmed S.Onour
相关产品推荐
相关产品推荐

