如何在Node.js中获取MariaDB查询结果并返回给客户端?
问题:Node.js/Express无法将MariaDB查询结果返回给客户端
近期开始自学Node.js搭建网站,需要从MariaDB中获取SELECT查询结果,最终将其作为JSON响应返回给客户端浏览器的POST请求。在网络及Stack Overflow上搜索过,但未找到相关解决方案。
编写的Node/Express代码可成功执行数据库查询并将结果打印到服务器控制台,却无法将查询结果返回给客户端。请问哪里遗漏了/做错了什么?
服务器端代码
(get_publishers和accessDB函数的代码基于'MariaDB Connector/Node.js (Promise API) Examples'中的示例)
const express = require('express') const mariadb = require('mariadb') // get list of publishers function get_publishers(conn) { return conn.query("SELECT * FROM publishers") } // get database SELECT query async function accessDB() { let conn let queryResult try { conn = await mariadb.createConnection({ host: "localhost", user: "****", password: "****", database: "*****" }) queryResult = await get_publishers(conn) console.log('db query complete') } catch (err) { console.log(err) } finally { console.log(queryResult) if (conn) conn.end() console.log('db connection closed') return queryResult } } const app = express() app.use(express.static(__dirname + '/public')) const http = require('http'); const fs = require('fs'); const port = process.env.PORT || 3000; app.get('/listPublishers', (req, res) => { res.type('text/plain') const now = new Date() res.send( now + ' query result = ' + JSON.stringify(accessDB())) // res.send(accessDB()) }) app.listen(port, () => console.log( 'bookStore 16:26 started with accessDB on http://localhost:${port}; ' + 'press Ctrl-C to terminate.....'))
服务器控制台输出(查询结果符合预期)
$ node bookstore.js bookStore 16:26 started with accessDB on http://localhost:${port}; press Ctrl-C to terminate..... db query complete [ { publisherID: 1, publisherName: 'Jonathon Cape' }, { publisherID: 2, publisherName: 'W. W. Norton & Co' }, { publisherID: 3, publisherName: 'Corgi Books' }, ... { publisherID: 10, publisherName: 'Gollanz' }, { publisherID: 11, publisherName: 'Continuum' }, meta: [ ColumnDef { collation: [Collation], ... type: 'SHORT' }, ColumnDef { collation: [Collation], ... type: 'BLOB' } ] ] db connection closed
客户端浏览器结果
Mon Oct 03 2022 15:15:14 GMT+0100 (British Summer Time) query result = {}
解决方案
问题核心在于**accessDB是异步函数,调用时没有等待它完成就直接序列化返回**,导致你拿到的是一个未完成的Promise对象,JSON.stringify后显示为{}。另外还有几个细节需要调整:
将路由处理函数改为异步,并使用
await获取查询结果
异步函数需要用await等待其执行完成,才能拿到实际的查询结果。修改/listPublishers路由:app.get('/listPublishers', async (req, res) => { try { const queryResult = await accessDB(); res.json({ timestamp: new Date(), result: queryResult }); } catch (err) { res.status(500).json({ error: '数据库查询失败', details: err.message }); } })修复
accessDB函数的错误处理与异步操作
当前accessDB的catch块只打印错误但没有重新抛出,导致路由无法捕获数据库错误;同时conn.end()是异步操作,需要加await确保连接正确关闭:async function accessDB() { let conn let queryResult try { conn = await mariadb.createConnection({ host: "localhost", user: "****", password: "****", database: "*****" }) queryResult = await get_publishers(conn) console.log('db query complete') } catch (err) { console.log(err) throw err; // 重新抛出错误,让上层路由处理 } finally { console.log(queryResult) if (conn) await conn.end(); // 等待连接关闭完成 console.log('db connection closed') return queryResult } }优化响应格式与启动日志
- 用
res.json()自动设置Content-Type为application/json,无需手动调用res.type() - 修复启动日志的模板字符串语法错误(单引号改为反引号):
app.listen(port, () => console.log( `bookStore 16:26 started with accessDB on http://localhost:${port}; ` + `press Ctrl-C to terminate.....` ))
- 用
修改后,客户端就能收到包含完整查询结果的JSON响应了。
内容的提问来源于stack exchange,提问作者gwyver
相关产品推荐
相关产品推荐

