从未运行的 Query 的神秘案件
Source: Dev.to
背景
上个周末,我在为个人网站重构代码时遇到了一个奇怪的 bug。我是个业余跑者,拥有一个记录所有跑步数据的页面。这些数据存储在Neon 数据库中,我通过自己定制的 nuxt‑neon 模块读取它们。
我在更新代码以匹配模块的最新改动,特别是更改按日期(年份和/或月份)过滤的方式。最初我使用的是字面字符串 WHERE 条件:
r.date BETWEEN '${fromDate}' AND '${toDate}'
我想尝试一种基于对象的语法:
where.push({
column: 'r.date',
condition: '>=',
value: fromDate,
});
where.push({
column: 'r.date',
condition: '`** – 我在想字面字符是否在某处被剥离或转义。
经过一天的死胡同,我向 Copilot 求助。它建议使用 curl 重现请求,以绕过任何前端噪音。这样做后,真正的罪魁祸首显现出来。
根本原因:Nuxt Security 的 XSS 防护
请求被 Nuxt Security 模块 拒绝,因为它的 XSS 攻击防护机制。出问题的代码位于:
...\node_modules\.pnpm\nuxt-security@2.4.0_magicast@0.3.5_rollup@4.52.5\
node_modules\nuxt-security\dist\runtime\server\middleware\xssValidator.js:38:18
Nuxt Security 将 “ 字符视为潜在的恶意脚本注入,导致请求被吞掉并返回神秘的 500 错误。
缓解措施
为了解决这个问题,我在客户端添加了一个内部映射,将尖括号转换为文字缩写,并在服务器端构造实际 SQL 查询时再转换回来。为了用户便利,我保留了原始符号的使用方式,提供 GT 和 LT 作为替代。
教训
1. 不要害羞,向 AI 求助
即使你不确定具体问题是什么,描述情境(“我为什么会出现这个错误?”)也能得到有价值的线索。
2. 隔离问题
当后端似乎没有响应时,直接调用接口(例如使用 curl)可以排除前端堆栈的干扰。
3. 考虑第三方软件的影响
问题可能来源于你并未编写的库或中间件。在本例中,Nuxt Security 的 XSS 验证器是隐藏的拦截因素。
结语
我已经从事软件开发二十余年,仍然会遇到一些琐碎且令人沮丧的 bug。分享这些经历可以提醒大家,即使是资深开发者也会卡住,而系统化的调试——加上一点 AI 的帮助——能够让我们重新回到正轨。
感谢阅读;希望这篇文章能帮助到将来遇到类似问题的朋友。