Node.js+Vue.js GET请求动态查询数据库字段问题解决
动态字段查询返回异常问题排查
问题背景
基于Node.js + Vue.js搭建表单功能,支持用户选择需要查询的数据库目标字段,根据选中内容发起对应数据查询,初始实现无法返回预期结果。
初始实现代码
前端fetch请求逻辑
temp_select: 'temperature' async exportData(){ const data_select = encodeURIComponent(this.temp_select); const url = `http://192.168.1.51:3000/api/v1/export/${data_select}`; fetch(url) .then(res => res.text()) .then((result) => { console.log(typeof(data_select)); const data = JSON.parse(result); console.log(data); }) .catch((error) => { console.log(error) }); },
后端初始查询逻辑
async function exportDatabase(req, res){ const data_selected = req.params.data_select; return db.any('SELECT $1 FROM tag_7z8eq73', [data_selected]) .then(rows => { res.json(rows) }) .catch(error => { console.log(error) }); }
异常表现
- 初始代码可正常发起数据库请求,但返回结果不符合预期,异常返回效果:

- 将SQL查询字段硬编码为
temperature时,功能可正常运行,对应代码如下:
async function exportDatabase(req, res){ return db.any('SELECT temperature FROM tag_7z8eq73') .then(rows => { res.json(rows) }) .catch(error => { console.log(error) }); }
正常返回效果:
问题根因
数据库驱动的参数化查询占位符($1)仅支持替换SQL中的值,不支持替换标识符(列名、表名等)。传入字段名时,驱动会将其作为字符串值处理,实际执行的SQL等价于SELECT 'temperature' FROM tag_7z8eq73,因此每一行返回的都是固定字符串temperature,而非对应列的存储值。
修正实现
注意:直接拼接用户传入参数存在SQL注入风险,生产环境请务必增加字段白名单校验,仅允许用户传入提前定义好的合法字段名。
- 前端fetch请求逻辑无需调整,保持原有代码即可。
- 后端调整SQL拼接逻辑,修正后代码如下:
async function exportDatabase(req, res){ const data_selected = req.params.data_select; // 生产环境请在此处增加白名单校验:判断data_selected是否在允许查询的字段列表内 return db.any('SELECT ' + data_selected + ' FROM tag_7z8eq73') .then(rows => { res.json(rows) }) .catch(error => { console.log(error) }); }
- 路由配置如下:
router.get('/export/:data_select', db.exportDatabase);
内容的提问来源于stack exchange,提问作者Barre Mathis
相关产品推荐
相关产品推荐

