Node.js 24 的 JSON.parse 把双引号键解析成反斜杠
特定转义键与前序对象形态会触发 V8 JSON 快速转换路径错误。保留原始字节,用代码点检查键值,并采用包含正式回补的 Node 24.22.1。
JSON 文本里第二个对象的键是双引号,JSON.parse() 后却变成了反斜杠,而且没有抛异常。若运行的是 Node.js 24.14.1 或 24.15.0,检查 V8 对转义对象键的解析路径,不能先认定输入 JSON 写错。
这个问题需要特定的前后对象形态:前面的单键对象使用反斜杠转义键,后面相同位置的单键对象使用另一个转义键。Node.js 24.22.1 已包含跳过转义键快速转换路径的 V8 回补。
用代码点区别反斜杠与双引号
下面使用 String.raw 保留 JSON 文本中的反斜杠,避免再套一层普通 JavaScript 字符串转义:
const text = String.raw`{"a":{"\\":1},"b":{"\"":2}}`;
const parsed = JSON.parse(text);
const firstKey = Object.keys(parsed.a)[0];
const secondKey = Object.keys(parsed.b)[0];
console.log(firstKey.codePointAt(0), secondKey.codePointAt(0));
按这段输入,两个代码点应分别是 92 和 34。若第二个仍是 92,就不是控制台把字符串显示得相似:对象键已经不同于输入的含义。增加第二个字段、改变之前的解析顺序或重启进程,可能改变现象,却不能证明问题已解决。
对于签名、规范化 JSON 或缓存键,错误可能在重新序列化后才被发现。保留原始字节、Node 与 V8 的实际版本,并用无敏感内容的最小输入定位;不要为了记录问题把业务载荷完整写进日志。
采用包含回补的正式运行时
Node.js 24.22.1 的正式发布与源码已包含 V8 修正:转义键不再进入这条快速转换路径。通过应用既有的版本管理和部署方式采用兼容补丁版,核对真实执行进程的版本;只更新开发机,不能修复仍在旧基础镜像中运行的服务。
这处错误不靠 reviver 回调解决。reviver 接收到的是解析后已经生成的属性,不能凭空恢复丢失的原始键。给所有反斜杠做字符串替换、手工添加字段,或关闭 JIT,也不能作为可靠修复;它们可能改变合法业务数据,且该问题并不限于 JIT 优化代码。
若因部署约束暂时不能更新,应按业务允许的范围隔离相关解析任务,采用经过独立兼容验证的运行环境;不要静默接受键已经变化的对象作为签名或校验输入。
比较输入语义,不只看 parse 是否成功
在应用实际使用的进程中检查上述两种键,以及嵌套对象、同对象增加其他字段、同进程连续多次解析的情况。验收目标是每个键和值符合原始 JSON,而不是只看函数返回了对象。
如果旧环境已经处理过需要保真的记录,先保留原文并核对受影响结果,再按业务规则决定是否重新处理。运行时更新不会自动修复此前已保存的错误对象;重新执行带有外部副作用的任务,也不应只由这条解析检查触发。


