You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在线JS游戏扩展中,如何Eval含控制字符的JSON字符串?

问题描述

我正在给一款在线JavaScript游戏写工具箱扩展,需要生成命令字符串传给注入脚本,由脚本用eval执行。现在遇到个问题:当要传递的对象包含控制字符(比如换行符\n)时,eval解析会失败。

可行场景(无控制字符)

const ObjectToPass = {a:"test"}
const ObjectStringified = JSON.stringify(ObjectToPass) // '{"a":"test"}'
const StringToPass = `Destination = JSON.parse('${ObjectStringified}')`
// 传递到主页面上下文后执行eval
eval(StringToPass) // Destination 成功赋值为 {a:"test"}

失败场景(含控制字符)

const ObjectToPass = {a:"test\n"}
const ObjectStringified = JSON.stringify(ObjectToPass) // '{"a":"test\\n"}'
const StringToPass = `Destination = JSON.parse('${ObjectStringified}')`
// 主页面执行eval后报错
eval(StringToPass) // 报错:Uncaught SyntaxError: Bad control character in string literal in JSON at position 10

我试过各种转义组合和双重stringify/parse,都没解决,比如这些尝试都失败:

eval(`JSON.parse('{"a":"\\n"}')`) // 报错:Invalid or unexpected token
eval(`JSON.parse('{"a":"\\n"}')`) // 报错:Bad control character...
eval(`JSON.parse('{"a":"\\\n"}')`) // 结果不对:{a: ''}
eval(`JSON.parse(\`{"a":"\\n"}\`)`) // 报错:Bad control character...

问题根源

问题出在字符串嵌套解析的转义层级:

  1. JSON.stringify把\n转成了\\n,得到的JSON字符串是'{"a":"test\\n"}'
  2. 当把这个字符串塞进单引号模板'${ObjectStringified}'后,最终传给eval的代码是Destination = JSON.parse('{"a":"test\\n"}')
  3. eval会先解析这个字符串字面量,把\\n变成实际的换行符\n,此时传给JSON.parse的内容变成了{"a":"test\n"}
  4. 而JSON规范不允许字符串里出现未转义的控制字符(比如实际的换行符),所以直接报错。

解决方案

方案1:直接传递JSON作为对象字面量(推荐)

不需要用JSON.parse,直接把JSON.stringify后的结果当作对象字面量赋值,跳过解析步骤:

const ObjectToPass = {a:"test\n"}
const ObjectStringified = JSON.stringify(ObjectToPass)
const StringToPass = `Destination = ${ObjectStringified}`
// 主页面执行eval
eval(StringToPass) // Destination 成功赋值为 {a:"test\n"}

这样eval会直接把JSON字符串当作JS对象解析,完全避开了转义冲突问题。

方案2:二次转义JSON字符串(如果必须用JSON.parse)

如果因为某些原因一定要用JSON.parse,需要把JSON字符串里的反斜杠再转义一次,确保eval解析后传给JSON.parse的是正确的转义序列:

const ObjectToPass = {a:"test\n"}
let ObjectStringified = JSON.stringify(ObjectToPass)
// 把所有反斜杠替换成双重反斜杠
ObjectStringified = ObjectStringified.replace(/\\/g, '\\\\')
const StringToPass = `Destination = JSON.parse('${ObjectStringified}')`
// 主页面执行eval
eval(StringToPass) // Destination 成功赋值为 {a:"test\n"}

此时传给eval的代码是Destination = JSON.parse('{"a":"test\\\\n"}'),eval解析后变成JSON.parse('{"a":"test\\n"}'),JSON.parse就能正确识别\\n为换行符。


内容的提问来源于stack exchange,提问作者Ufodynasty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 11:15:38