JavaScript处理动态脚本的核心原则是不执行不可信字符串、优先用结构化方式替代eval;JSON仅含数据类型,混入函数等即越界;应校验Content-Type、首尾空白及HTML特征,用try-catch包裹JSON.parse()解析,禁用eval,必要时用new Function()限作用域并参数传值,辅以schema校验与safeJsonParse封装。

JavaScript 中处理动态脚本内容,核心原则是:**不执行不可信字符串,优先用结构化方式替代 eval**。JSON 本身是数据格式,不是代码;一旦混入可执行逻辑(比如服务端返回带函数体的字符串),就跨出了 JSON 安全边界。真正需要“动态执行”的场景,往往可通过更可控的方式实现。
明确区分 JSON 数据与可执行代码
JSON 规范只允许字符串、数字、布尔、null、数组和对象——它不含函数、undefined、Symbol 或任意 JS 表达式。如果后端返回的内容包含 function(){}、alert()、eval 调用等,那它已不是合法 JSON,而是被污染的字符串。此时不应尝试“解析+执行”,而应拦截并报错。
- 接收响应后,先检查
Content-Type是否为application/json,但不依赖它 - 用
trim()去除首尾空白,再判断是否为空或仅含空白字符 - 若开头是
<!、<html、<div等,大概率是 HTML 错误页,直接拒绝解析
用 JSON.parse() 替代 eval 解析数据
eval 执行任意代码,风险极高;JSON.parse() 只解析严格语法的 JSON,天然免疫代码注入。即使字符串被篡改(如插入 __proto__ 或构造器调用),只要不符合 JSON 语法,parse 就会抛错,不会执行。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 永远用
try...catch包裹JSON.parse(),捕获SyntaxError - 不要写
eval('(' + str + ')')—— 这等于主动打开攻击面 - 对已知结构的数据,可用可选链
?.和空值合并??防止访问崩溃,例如data?.user?.name ?? 'Anonymous'
真需动态执行时,用 Function 构造器限制作用域
若业务确实要求运行用户输入的表达式(如公式引擎、低代码规则),eval 必须禁用。new Function() 是更安全的替代:
立即学习“Java免费学习笔记(深入)”;
- 它创建的函数默认在全局作用域外执行,无法访问当前闭包变量
- 可显式传入白名单参数,例如
new Function('a', 'b', 'return a + b') - 配合正则预检(如禁止
import、document、window等关键词)进一步过滤 - 避免拼接用户输入进函数体,优先用参数传递数据
结构校验比解析更重要
解析成功不等于数据可用。字段缺失、类型错乱(如 "id": "123" 本该是 number)、嵌套路径断裂,都会导致后续逻辑异常。
- 对关键字段做类型守卫:
typeof data?.count === 'number' - 使用轻量校验库(如 zod 的
safeParse)或手写 schema 检查 - 封装统一的
safeJsonParse(text)工具函数,返回{ ok: boolean, data: any, error?: Error } - 前端日志中记录原始响应文本,便于排查非 JSON 响应来源

















