如何存储GET请求返回数据至变量?及数据库匹配时错误对象为空问题
嘿,我来帮你搞定这两个问题!你的代码里主要是异步操作处理不当和函数设计逻辑混乱导致的问题,咱们一步步拆解解决:
问题根源分析
首先看你遇到的两个问题,其实是同一个核心问题衍生出来的:
- GET请求数据存不到变量里:因为
con.query是异步操作,你的checkIfExists函数直接同步返回了结果,这时候数据库查询还没完成,自然拿不到数据。 - 有匹配条目但errors为null:同样是异步的锅,函数返回时,
query的回调还没执行,errors还是初始的空对象,所以看起来是null。
另外你的代码还有几个坑:
- 把路由定义
router.get放在工具函数里,这完全不合理,路由应该是独立的请求处理器,工具函数只负责业务逻辑。 - 直接用
${data}拼接SQL,这是高危SQL注入风险,绝对不能这么干! result是查询返回的数组(SELECT返回多条记录),你直接访问newData.particulars会报错,因为数组没有这个属性。newData没声明就使用,会变成全局变量,这是不良编码习惯。
修正后的代码方案
我们把代码拆成工具函数和路由处理器两部分,用异步/等待处理数据库操作:
1. 重构检查工具函数
这个函数专门负责检查特定条目是否存在,返回Promise方便异步调用:
const con = require("../config/keys"); const Validator = require("validator"); const isEmpty = require("./is-empty"); // 改成异步函数,返回Promise module.exports = async function checkIfExists(data, table) { let errors = {}; try { // 先验证表名合法性,防止SQL注入(表名不能用参数化占位符) const allowedTables = ["your_table_name1", "your_table_name2"]; // 替换成你实际的表名 if (!allowedTables.includes(table)) { errors.table = "Invalid table name"; return { errors, isUnique: isEmpty(errors) }; } // 使用参数化查询避免SQL注入,??对应表名,?对应值 const query = `SELECT * FROM ?? WHERE particulars = ?`; // 用promise包装数据库查询,支持await const [result] = await con.promise().query(query, [table, data]); // 判断是否有匹配记录 if (result.length > 0) { errors.particulars = "Particulars already exists"; } return { errors, isUnique: isEmpty(errors) }; } catch (err) { errors.database = "Failed to connect with database"; return { errors, isUnique: isEmpty(errors) }; } };
2. 独立定义路由处理器
路由单独处理请求,调用上面的工具函数完成检查:
const express = require("express"); const router = express.Router(); const checkIfExists = require("./path-to-your-check-function"); // 替换成工具函数的实际路径 // 处理GET请求的路由 router.get(`/tools/:table`, async (req, res) => { try { const { table } = req.params; const particulars = req.query.particulars; // 假设你从URL参数获取要检查的particulars // 先验证参数是否存在 if (!particulars) { return res.status(400).json({ errors: "Particulars parameter is required" }); } // 调用异步检查函数,等待结果 const { errors, isUnique } = await checkIfExists(particulars, table); if (!isUnique) { return res.status(400).json(errors); } res.json({ message: "Particulars is unique", isUnique }); } catch (err) { res.status(500).json({ errors: "Server error" }); } }); module.exports = router;
关键修改点说明
- 异步处理:用
async/await等待数据库查询完成,确保拿到结果后再返回错误信息,解决了数据存不到变量和errors为空的问题。 - SQL注入防护:使用参数化查询(
??和?占位符),同时验证表名合法性,彻底避免注入风险。 - 职责分离:路由负责处理请求响应,工具函数专注于业务逻辑,代码更清晰易维护。
- 结果正确处理:通过
result.length > 0判断是否有匹配记录,不再错误访问数组的属性。
这样修改后,当数据库存在匹配的particulars时,errors.particulars会被正确设置,你也能通过await拿到查询结果并存储到变量里啦!
内容的提问来源于stack exchange,提问作者Dipanshu Chaubey
相关产品推荐
相关产品推荐

