使用node-postgres如何持久化数据库查询结果并后续访问?
嘿,我看到你遇到的问题了——核心原因是Node.js的异步操作特性,再加上你对Express路由传参方式的误解,咱们一步步拆解解决:
先说说你代码里的几个明显问题
- SQL语句写错了:
SELECT idartiste * FROM artiste);多了多余的*和闭合括号),正确写法应该是SELECT idartiste FROM artiste;(如果要查所有字段就用SELECT * FROM artiste;) rows变量的作用域和异步时机错了:就算你把它设成全局变量,db.query是异步操作,POST路由函数会直接执行完毕,不会等数据库查询回调触发。等GET路由执行时,回调可能还没跑,rows自然是undefined- 你尝试的
.post('/route', data ,function(req, res){ ... })完全不符合Express路由规则:路由的第二个参数只能是中间件函数,不能直接传变量
给你几个靠谱的解决方案
方案1:用Session存查询参数,在GET路由里完成查询(最常用的场景)
思路是POST路由只负责接收用户的搜索关键词,存在Session里,然后重定向到结果页,由GET路由去数据库查询并返回结果:
// 前提:你已经配置了express-session中间件 .post('/musicbrainz/research/', function(req, res){ // 把用户输入的关键词存在session中 req.session.searchKeyword = req.body.recherche; // 重定向到结果页 res.redirect('/musicbrainz/results/'); }) .get('/musicbrainz/results/', async function(req, res, next){ try { const keyword = req.session.searchKeyword; if (!keyword) { // 如果没有搜索参数,返回搜索页面 return res.redirect('/musicbrainz/research/'); } // 用参数化查询避免SQL注入,这里假设你要按艺术家名称查询 const query = "SELECT idartiste FROM artiste WHERE nom = $1;"; // 用await等待异步查询完成,确保拿到结果再往下走 const queryResult = await db.query(query, [keyword]); const rows = queryResult.rows; // 这里就可以用rows渲染页面或者返回数据了 res.render('results-page', { results: rows }); // 假设用模板引擎渲染页面 } catch (err) { // 把错误传给错误处理中间件 next(err); } })
方案2:用异步中间件在POST路由内完成查询,把数据存在req对象中
如果你不想重定向,想在POST请求后直接返回结果,可以用async/await确保查询完成,再把数据挂载到req对象上给后续中间件用:
.post('/musicbrainz/research/', async function(req, res, next){ const keyword = req.body.recherche; try { const query = "SELECT idartiste FROM artiste WHERE nom = $1;"; const queryResult = await db.query(query, [keyword]); // 把查询结果存在req对象里,后续中间件可以直接访问 req.artisteResults = queryResult.rows; // 调用下一个中间件 next(); } catch (err) { return next(err); } }, function(req, res){ // 这个函数是POST路由的后续处理逻辑,直接在这里返回结果 const results = req.artisteResults; res.json({ success: true, data: results }); // 返回JSON数据,或者渲染页面 })
再强调下核心逻辑
Node.js里的数据库查询是异步操作,你的代码不能假设回调函数会同步执行——必须用async/await、Promise或者回调嵌套(不推荐)来确保数据准备好后再执行后续逻辑。另外,绝对不要用全局变量存请求相关的数据,会导致多用户并发请求时数据混乱,用req对象或者Session才是安全的做法。
内容的提问来源于stack exchange,提问作者Nillem
相关产品推荐
相关产品推荐

