全部文章
NINTHLESS / NOTE

给不断变化的 Web 应用做汉化,难点不是翻译

我在维护 Postman-Web-i18n 时发现,动态 DOM、状态原子性、规则安全和扩展权限比翻译字典更难。

刚开始做汉化时,我以为把英文字符串替换成中文只需要一个字典。真正让我反复修改的,是如何让一个持续更新、动态渲染的 Web 应用长期稳定地显示中文:DOM 生命周期、组件结构、状态切换、用户规则、浏览器权限和安全边界都不能绕过。

我在 2025 年 10 月建立 Postman-Web-i18n,最初就放入内容脚本、翻译文件、设置页、弹窗和构建流程。真正让我意识到“能翻译”不等于“可以维护”的节点,是 2026 年 5 月的一次质量审计。

时间线:14 个问题如何暴露系统结构

2025-10-17:建立完整扩展骨架

初始版本里,我覆盖了 Chrome/Edge、动态内容翻译、多语言文件、自定义规则、设置导入导出和自动发布。功能面已经很宽,但功能越多,状态组合也越多。

2026-05-25:P0 安全与数据问题

第一批修复里,我处理了四类基础问题:

  • 用户开关中的 false 被默认值逻辑覆盖。
  • 自定义规则通过 innerHTML 渲染,形成 XSS 风险。
  • 导入翻译的入口存在,但缺少完整实现和活动页面通知。
  • 代码调用标签页 API,却没有在清单中声明对应权限。

它们看似分散,实际都来自同一个问题:界面状态、持久化状态、扩展权限和页面状态没有形成闭环。

2026-05-25:P1 原子性与规则校验

第二批修复为语言切换增加状态快照与失败回滚,避免加载失败后页面变成空白;自定义规则在保存前检查选择器白名单、非空键值和正则合法性;文本替换从局部字符串操作改为明确赋值,减少翻译污染。

2026-05-25:P2 兼容与完整性

最后一批修复处理占位符全量替换、子元素保留、动画时序、语言兼容和重复值检查范围。最终 14 个 P0/P1/P2 问题在同一个审计分支中合并。

动态页面不是一棵静止的 DOM 树

现代 Web 应用会在路由切换、请求返回、虚拟列表滚动和组件状态变化时持续重建节点。扩展不能只在 DOMContentLoaded 后扫描一次。

Chrome 官方把 content script 运行在隔离环境中。它可以读取和修改页面 DOM,但与宿主页面的 JavaScript 世界分离。这个边界保护了变量作用域,却没有自动解决动态内容、重复翻译和组件更新问题。

可靠的翻译器需要区分:

  • 首次扫描与后续增量节点。
  • 文本节点、占位符、标题和无障碍标签。
  • 原文、已翻译文本和用户编辑内容。
  • 整段匹配与局部匹配。
  • 被框架销毁后重新创建的节点。

如果没有幂等性,同一节点被观察两次就可能二次翻译;如果替换粒度太粗,给 label.textContent 赋值可能顺便删除图标或子组件。

本地化切换必须是一笔事务

语言切换通常包含多个步骤:读取目标语言、更新内存状态、保存设置、重翻页面、通知其他扩展页面。任何一步失败,都可能留下“设置显示中文,但页面仍是英文”或“旧字典已清空,新字典未加载”的半完成状态。

更稳妥的模型是:

保存旧状态 → 加载并校验新语言 → 一次性提交 → 通知页面
                 失败 ↓
              恢复旧状态

这就是原子性。它不要求数据库,只要求把状态变化当作不可分割的用户操作。

自定义规则是代码输入

允许用户输入 CSS 选择器和正则表达式,会显著提高扩展能力,也会把配置变成一种小型程序。

规则至少需要验证:

  • 选择器类型是否在允许集合中。
  • 正则是否能编译,是否可能造成异常开销。
  • 翻译键是否存在或明确属于自定义命名空间。
  • 显示规则时是否使用安全 DOM API。
  • 导入数据是否符合预期结构与大小限制。

Chrome 的扩展安全指南 建议把来自内容脚本和用户输入的数据视为不可信,并最小化权限。扩展拥有比普通网页更高的能力,设置页中的一个 XSS 不能被当作普通显示瑕疵。

Manifest V3 改变了默认假设

Manifest V3 不允许扩展执行远程托管代码,并用 Service Worker 替代长期后台页面。它的方向是让代码进入可审查包、减少常驻资源,并让权限更明确。

对于本地化扩展,这意味着:

  • 翻译逻辑应随扩展打包,不能从远端下载脚本后执行。
  • 远端更新适合传输数据,但数据仍需严格校验。
  • 主机权限只覆盖确实需要翻译的站点。
  • 新增 tabsscripting 等权限时,要能说明具体用途。

权限清单既是技术配置,也是用户可见的信任声明。

翻译质量不只是一致率

翻译文件可以通过缺失键、重复值和占位符检查,但最终质量还包括界面语义:

  • 按钮文本是否在动作语境中自然。
  • 术语在请求、集合、环境和测试等上下文中是否一致。
  • 中文变长后是否挤压布局。
  • 快捷键、变量名、代码和用户数据是否被误翻。
  • 屏幕阅读器使用的 aria-label 是否同步。

因此,自动检查适合发现结构问题,真实页面巡检负责发现语境问题。两者不能互相替代。

一个稳定翻译扩展的最小测试矩阵

维度 至少检查
页面生命周期 首次加载、路由切换、弹窗、延迟内容
文本结构 纯文本、含图标子元素、占位符、ARIA
语言状态 首次选择、快速切换、加载失败、重启恢复
自定义规则 合法、非法正则、危险文本、重复规则
权限 新装、升级新增权限、无权限降级
浏览器 Chrome、Edge、目标最低版本

“翻译了多少字符串”只能衡量覆盖率。一个汉化扩展真正的可靠性,取决于页面变化时是否保持结构、失败时是否恢复状态、用户规则是否被安全处理。

相关链接