Chromium WebUI 深度解析:src/ui/webui/resources 的架构定位与运行机制

「鸿蒙心迹」“2025・领航者闯关记“主题征文活动 10w+人浏览 630人参与

在 Chromium 内核开发中,WebUI 是浏览器原生 UI 的重要组成部分,它既提供了诸如 chrome://settingschrome://downloads 等页面的交互能力,又承担了浏览器安全与权限保护的重任。对于很多开发者来说,src/ui/webui/resources 目录看似只是一个“公共 JS / CSS 库”,但实际上,它承载了 Chromium WebUI 的安全、运行时和基础设施职责,是 WebUI 生态的“宪法”。

本文将从历史背景、架构定位、运行机制、安全模型、以及它与业务模块的交互方式等五个层面,做一次工程级深度剖析。


一、历史与背景:为什么会有这个目录?

1️⃣ WebUI 的原始问题

Chromium 的 WebUI 页面是用 HTML / JS 实现的,但它有一个天然矛盾:

  • 运行在 Browser Process:意味着拥有极高权限。

  • 能调用 Mojo / C++ / 系统能力:比如直接操作密码、下载文件等。

  • 天然 XSS 风险:一旦 HTML 被注入恶意内容,整个浏览器都可能被攻破。

在 Chrome 30~40 年代,WebUI 页面非常“野”,常见问题包括:

  • i18n 字符串直接 innerHTML 插入页面;

  • 翻译文件可能被翻译人员加入 <a><img><script> 等 HTML 标签;

  • 多语言文件由外包维护,安全审计难度大;

  • 历史上真实发生过安全事故,浏览器被打穿。

2️⃣ Chromium 的战略选择

为了解决这个安全矛盾,Chrome 团队做出了工程化的决定:

WebUI 必须被当成浏览器内核的一部分,而不是普通网页。

因此诞生了 src/ui/webui/resources

  • 定位:WebUI 的“标准库 + 安全基线 + UI 基础设施”。

  • 职责:为所有 WebUI 页面提供统一运行时、i18n 安全处理、DOM 子集约束等功能。

它不是具体业务模块,而是WebUI 的运行时基础设施


二、架构定位:它在 WebUI 中的角色

1️⃣ 它不是业务代码

src/ui/webui/resources 并不属于业务模块,例如:

  • chrome://settings

  • chrome://password-manager

  • chrome://downloads

而是所有 WebUI 页面共同依赖的 runtime。可以类比为:

类比对象对应
C++ STLWebUI runtime
libc浏览器 WebUI 基础层
Blink 对 DOM 的限制WebUI 对 HTML 的限制

2️⃣ 典型目录结构

src/ui/webui/resources/
├── js/
│   ├── parse_html_subset.js   ⭐ 安全核心
│   ├── i18n_mixin.js          ⭐ i18n 入口
│   ├── cr.js                  ⭐ 框架 glue
│   ├── util.js
├── cr_elements/               <cr-button> 等
├── css/
├── images/
  • parse_html_subset.js:WebUI 核心安全裁判。

  • i18n_mixin.js:i18n 文案加载和安全插入。

  • cr.js:模块定义和初始化 glue。

  • cr_elements:基础 WebUI 元素组件库。


三、核心机制:它是如何“裁判”的?

1️⃣ 核心设计思想

WebUI 不允许自由 HTML,只允许受控 HTML 子集。

  • parse_html_subset.js 定义白名单;

  • 任何超出范围的 HTML 会被拒绝或抛异常。

2️⃣ parse_html_subset.js 的功能

  • 允许的 tag<b> <i> <br> <p> <a> <span>

  • 允许的 attribute<a href><span class>

  • 禁止的内容<script><img>onClickonLoad、任意未知 tag

  • 禁止 style:默认禁止 style="background:url(...)"

3️⃣ 运行流程示例

业务调用链:

i18nAdvanced
└── sanitizeInnerHtml
    └── sanitizeInnerHtmlInternal
        └── parseHtmlSubset
  • 业务模块 调用 i18nAdvanced 生成 HTML;

  • resources 强制 sanitize;

  • 超出白名单 → 抛异常。

注意:这是设计行为,不是 bug。


四、i18n 的安全模型

1️⃣ 为什么 i18n 是重点对象

i18n 字符串来自 .grdp / .xtb 文件,由非工程师翻译。历史上存在翻译文件加入 <img>javascript: 的情况,直接威胁浏览器安全。

2️⃣ i18n API 设计

API用途
i18n()纯文本(安全)
i18nAdvanced()限制 HTML(经过 parse_html_subset)

3️⃣ 为什么 password_manager 常出异常

常见雷区:

  • <a target="_blank">target 不在白名单

  • <br/> → 自闭合形式

  • <span style=...> → style 禁止

  • <strong> → 不在白名单

资源层抛异常是为了集中、早期发现问题,而不是“resources 有 bug”。


五、resources 如何与业务模块交互

1️⃣ 架构模型

Browser Process (C++)
├── WebUIController
├── WebUIMessageHandler ◄── Mojo / IPC
└── DataSource (strings)
          │
          │ JS bindings (chrome.send / mojo)
WebUI 页面(业务模块)
├── password_manager.js
├── settings.js
└── downloads.js
        ▲
        │ import / mixin
    i18nAdvanced()
    cr.js
    parse_html_subset.js
└─────────────┬──────────────┘
src/ui/webui/resources (runtime / infra)
  • 调用方向:业务 → resources

  • 资源目录不主动通信;

  • 它是 WebUI 的 runtime / 标准库。

2️⃣ 三种交互方式

1️⃣ Mixin / Base Class 注入

export const I18nMixin = (superClass) => class extends superClass {
  i18n(id, ...args) {
    return loadTimeData.getString(id, args);
  }

  i18nAdvanced(id, ...args) {
    return sanitizeInnerHtml(
      loadTimeData.getString(id, args));
  }
};
  • 业务模块继承 mixin;

  • runtime 改变行为;

  • 编译期 + 运行期融合。

2️⃣ 全局函数 / 约定

  • sanitizeInnerHtml

  • parseHtmlSubset

  • cr.define()

  • loadTimeData

提前注入 WebUI JS 全局,可视为“系统调用接口”。

3️⃣ WebUIDataSource + JS runtime 协作

  • C++ 侧注入字符串:WebUIDataSource::AddLocalizedString

  • JS 侧通过 loadTimeData.getString() 获取;

  • i18n / i18nAdvanced 基于 resources 提供的 runtime 处理。

C++ 不直接和业务 JS 通信,resources 是中介层。


六、为什么不让业务模块直接通信?

  • 防止野生前端:自由 innerHTML → XSS 风险

  • 统一 runtime:保证安全模型一致

  • 统一通信方式:集中管理 C++ / Mojo 调用


七、和 C++ / Mojo 的关系

  • resources 不直接调用 Mojo

  • 不 import 业务接口

  • 它只提供封装、约束和防护。

业务模块需要调用 C++ / Mojo,必须走 WebUIController + WebUIMessageHandler → Mojo → resources 提供的 runtime 接口。


八、工程级总结

  • src/ui/webui/resources 是 WebUI 的“宪法”,业务模块只能遵守,不能挑战。

  • 它提供 runtime / 安全裁决 / i18n 支持,但不主动通信。

  • 所有异常堆栈指向它,是“最后门卫”,而不是问题根源。

  • 修改它必须谨慎,否则破坏浏览器安全模型。


九、工程建议

  • 遇到 WebUI 页面抛异常,不要改 resources;

  • 修正 业务文案 或降级 i18nAdvanced → i18n;

  • 避免非法 HTML,遵循 parse_html_subset 白名单。


十、附录:核心目录与机制复盘

文件功能
parse_html_subset.jsHTML 白名单裁决
i18n_mixin.jsi18n / i18nAdvanced 封装
cr.js模块 glue,注册全局定义
util.js常用工具函数
cr_elements/<cr-button> 等 WebUI 基础组件
css/公共样式
images/公共资源

调用顺序:

  1. 业务 JS 生成 HTML 文案 → i18nAdvanced()

  2. parse_html_subset.js 校验合法性

  3. sanitizeInnerHtml 处理异常

  4. 注入 DOM


十一、工程师视角结论

  • 业务模块 = 用户

  • resources = 系统调用接口 + runtime + 审查机制

  • parse_html_subset = 内核裁决

理解这一点,你才能:

  • 不再误认为 resources 是“功能模块”

  • 正确定位问题根源在业务文案或调用方式

  • 安全地扩展 WebUI 功能


🔥 工程金句
src/ui/webui/resources 是 WebUI 的宪法,业务模块只能遵守,不能挑战。
parse_html_subset.js 是 WebUI 的内核裁决,不是 bug 根源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ปรัชญา แค้วคำมูล

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值