proxy 通过 set 陷阱捕获点号路径赋值,生成快照并记录审计日志;回滚按路径还原 oldvalue;审计通过 onauditlog 回调外发,规避函数、symbol 和只读字段。

Proxy 本身不直接提供回滚或持久化审计能力,但它能作为数据变更的“守门人”,在 set 陷阱中精准捕获每一次赋值操作——这是构建自动回滚与审计记录层的关键起点。核心思路是:不依赖深层递归代理(易循环、开销大),而是聚焦字段路径 + 变更快照 + 显式生命周期控制。
用点号路径标识字段,统一拦截入口
约定所有可治理字段使用点号分隔的字符串路径(如 "user.profile.phone" 或 "order.items.0.price"),避免对嵌套对象做 Proxy 嵌套。在 set 陷阱中判断 key 是否含 .,若是,则走路径解析分支:
- 逐级访问目标属性前,先读取当前值(
getByPath(target, key))生成变更前快照 - 执行赋值后,立即记录一条审计条目:
{ path: key, oldValue, newValue, timestamp, operator } - 将该快照与操作元信息存入一个轻量变更栈(如数组或 Map),供后续回滚调用
回滚不是“撤销 Proxy”,而是还原字段快照
回滚动作不修改 Proxy 结构,只按路径还原历史值。设计一个 rollback(path) 方法:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 从变更栈中查出该路径最近一次成功 set 的
oldValue - 调用
setByPath(target, path, oldValue)直接写回原始值 - 同步从栈中移除该条目(或标记为已回滚),避免重复回滚
- 支持批量回滚(传入路径数组)和事务级回滚(按时间戳范围回退)
审计记录需结构化,且可扩展导出
每条审计日志应包含最小必要字段:path、oldValue、newValue、timestamp、source(如 "user-input" / "api-sync")、contextId(关联业务单据 ID)。不建议在 Proxy 内部做存储,而是通过回调通知外部审计服务:
- 初始化时注入
onAuditLog回调函数,每次 set 后触发 - 回调中可做脱敏(如隐藏手机号中间四位)、异步上报、写入本地 IndexedDB 或发往日志中心
- 若需持久化本地记录,可用
localStorage存储最近 N 条,配合 TTL 清理
规避常见陷阱:只代理可变字段,不碰不可变结构
不要对整个业务模型对象无差别 Proxy,尤其避开以下情况:
- 方法属性:过滤掉函数类型属性,避免误拦截调用逻辑
- Symbol 键:默认跳过 Symbol 类型 key,防止干扰内部状态
-
只读字段:通过
rules[path] = { readOnly: true }配置,set 时直接 throw 或静默忽略 -
非业务字段:如
__v、_id、createdAt等,可在 handler 中白名单放行或跳过审计










