
前端UI组件【免费下载链接】fastThe adaptive interface system for modern web experiences.项目地址https://gitcode.com/gh_mirrors/fa/fast点击查看免费下载FAST Elementmicrosoft/fast-element作为微软开源的 Web Components 高效渲染引擎其模板系统在将 HTML 字符串写入 DOM 之前需要一道安全边界。TrustedTypes类型正是 FAST Element 对接浏览器原生 Trusted Types API可信类型的入口类型它封装了策略创建能力让框架与应用的 HTML 生成行为能够被 CSPContent Security Policy纳入审计与管控。本文将以 1.x API 参考文档中的TrustedTypes类型 为骨架结合当前仓库的 dom.ts、dom-policy.ts 与相关测试源码系统讲解该类型的定义、内部使用方式以及在应用中配置自定义 Trusted Types 策略的完整实战方案。一、TrustedTypes 类型类型签名与语义解析在 1.x 的 API 文档中TrustedTypes被定义为一个结构化的 TypeScript 类型全文核心签名如下export declare type TrustedTypes { createPolicy(name: string, rules: TrustedTypesPolicy): TrustedTypesPolicy; };该类型是 FAST Element 对浏览器globalThis.trustedTypes全局对象的类型化抽象其唯一成员createPolicy的语义逐字段解析如下成员类型说明namestring待创建策略的名称。该名称必须出现在页面 CSP 的trusted-types指令白名单中否则浏览器的 Trusted Types 强制策略会拒绝创建并抛出异常。rulesTrustedTypesPolicy策略规则对象至少需要提供createHTML(html: string): string工厂方法决定一段 HTML 字符串如何被标记为可信。返回值TrustedTypesPolicy创建成功后返回可用于生成可信 HTML 的策略实例。用一句话概括TrustedTypes类型的职责是支持与 Trusted Types 协作文档原文Enables working with trusted types它把浏览器原生的策略创建接口收窄为 FAST Element 需要的最小形状供框架内部以及应用初始化代码直接调用。配套类型TrustedTypesPolicyTrustedTypes.createPolicy的入参与返回值都指向另一个公开类型TrustedTypesPolicy。在同目录的 fast-element.trustedtypespolicy.md 中它的定义同样简洁export declare type TrustedTypesPolicy { createHTML(html: string): string; };从当前仓库源码看该类型定义在 interfaces.ts注释明确为A policy for use with the standard trustedTypes platform API并标注为public。它是 FAST Element 整个可信类型体系的最小公约数无论是框架内置的fast-html策略还是应用自定义的富文本策略最终都必须满足接收原始 HTML 字符串、返回可信 HTML 字符串这一契约。配套类型GlobalTrustedTypes还出现在平台全局类型Global中。见 fast-element.global.mdexport declare type Global typeof globalThis { trustedTypes: TrustedTypes; readonly FAST: FASTGlobal; };这从类型层面确认了 FAST Element 将trustedTypes视为平台全局能力的一部分在支持 Trusted Types 的浏览器环境中globalThis.trustedTypes天然具备TrustedTypes类型的形状在不支持的环境中框架与开发者则需要自行构造符合该形状的降级实现详见下文。二、源码探秘fast-element 内部如何创建 Trusted Types 策略类型定义之外真正体现TrustedTypes价值的是它在框架内部的落地。当前仓库 dom.ts 中有一段关键实现const createHTML html html; const fastTrustedType: TrustedTypesPolicy globalThis.trustedTypes ? globalThis.trustedTypes.createPolicy(fast-html, { createHTML }) : { createHTML };这段代码完整对应了TrustedTypes.createPolicy(name, rules)的调用形状并揭示了 FAST Element 的三个设计决策默认策略名固定为fast-html框架在启动时通过globalThis.trustedTypes.createPolicy(fast-html, ...)注册自己的策略。这意味着如果应用的 CSP 声明了trusted-types指令必须把fast-html加入白名单否则框架的默认策略创建会被浏览器拒绝。createHTML默认原样返回框架自产的模板字符串被视为可信源代码策略仅做包装而不做净化。真正的用户输入净化需要交给应用层级的 sink 守卫见第四节。无 Trusted Types 环境的优雅降级当globalThis.trustedTypes不存在时直接退化为{ createHTML }普通对象与原生策略拥有完全相同的函数形状保证框架在不支持可信类型的浏览器中依然可用。同样的模式也出现在 dom-policy.ts 的createTrustedType()辅助函数中作为DOMPolicy.create()的默认可信类型来源function createTrustedType() { const createHTML html html; return globalThis.trustedTypes ? globalThis.trustedTypes.createPolicy(fast-html, { createHTML }) : { createHTML }; }这条创建链路TrustedTypes.createPolicy→fast-html策略 →DOMPolicy.createHTML正是TrustedTypes类型在 FAST Element 渲染管线中的实际位置模板编译器把 HTML 字符串交给 DOMPolicyDOMPolicy 委托给trustedType.createHTML()而该函数来自上述基于TrustedTypes类型创建出的策略对象。三、TrustedTypes 与 DOMPolicy可信类型的双层安全体系要理解TrustedTypes的完整作用域需要把它放进 FAST Element 的安全模型DOMPolicy中看。当前仓库在 dom-policy.ts 定义了DOMPolicy接口它承担两项职责职责方法说明生成可信 HTMLcreateHTML(value: string): string把模板编译的 HTML 字符串转换为可信 HTML内部委托给TrustedTypesPolicy即fast-html策略保护 DOM sinkprotect(tagName, aspect, aspectName, sink): DOMSink决定绑定值写入属性、布尔属性、DOM 属性、内容节点、token list、事件等位置时框架实际调用哪个 sink从源码结构看TrustedTypes处于安全模型的第一层可信 HTML 的生成DOMPolicy.protect处于第二层危险 sink 的拦截与改写。二者配合形成了模板字符串可信化 绑定写入审计的双层防线。DOMPolicy.create()dom-policy.ts在创建策略时的默认行为包括未显式传入trustedType时调用createTrustedType()生成名为fast-html的策略装载默认守卫规则覆盖内联事件属性on*、innerHTML属性、URL 类属性a[href]、iframe[src]等、script文本、iframe[srcdoc]等危险 sinkdom-policy.ts其中 URL 属性经过sanitizeURL净化、embed/object/link/script等元素的相关 sink 直接block。为什么绑定 innerHTML 必须提供 TrustedTypesPolicy在 1.x 中绑定innerHTML与 Trusted Types 的关系在 debug.ts 的错误消息中留下了直接证据[1202 /* bindingInnerHTMLRequiresTrustedTypes */]: To bind innerHTML, you must use a TrustedTypesPolicy.也就是说当绑定目标是innerHTML这类 HTML 注入点而又没有可用策略时框架会抛出该错误要求调用方显式提供TrustedTypesPolicy。这也印证了TrustedTypesPolicy不是可有可无的类型标注而是框架在运行时强制的安全契约。四、实战在应用中配置自定义 Trusted Types 策略理解了类型与内部实现后应用开发者最常遇到的问题是如何让 FAST Element 与自己的 CSP 策略协作。核心思路是利用DOM.setPolicy()安装全局策略再用DOMPolicy.create({ trustedType })把自定义的 Trusted Types 策略挂载进去。DOM.setPolicy()定义于 dom.ts有两个关键约束只能调用一次一旦全局策略被替换过再次调用会抛出onlySetDOMPolicyOnce错误码 1201异常这是出于安全考虑的设计应在应用启动时、组件定义与模板编译之前调用模板编译、渲染都会读取DOM.policy作为默认策略。一个标准的启动期配置示例如下import { DOM } from microsoft/fast-element/dom.js; import { DOMPolicy } from microsoft/fast-element/dom-policy.js; // 创建自定义 Trusted Types 策略对应 TrustedTypes.createPolicy 的调用形状 const trustedType globalThis.trustedTypes?.createPolicy(app-fast-html, { createHTML(html) { // FAST 模板是框架自产的源代码此策略只做包装 // 用户输入净化请在 sink 守卫中完成。 return html; }, }) ?? { createHTML: html html }; // 一次性安装全局策略 DOM.setPolicy(DOMPolicy.create({ trustedType }));其中globalThis.trustedTypes?.createPolicy(...) ?? { createHTML: html html }这一写法正是对TrustedTypes类型支持与可信类型协作、同时兼容无该 API 环境语义的最佳实践落地有原生 API 时走正式策略创建无原生 API 时回退为形状等价的普通对象。CSP 白名单注意事项如果应用的 CSP 启用了trusted-types指令必须把应用创建的所有策略名如上面示例的app-fast-html以及依赖框架内置策略时的fast-html一并加入白名单否则浏览器会阻止策略创建并产生 CSP 违规报告Content-Security-Policy: script-src self unsafe-inline; trusted-types app-fast-html fast-html;为富文本 innerHTML 绑定定制策略当业务确需将净化后的 HTML 绑定到:innerHTML时由于默认守卫规则会拦截innerHTML属性写入需要显式创建带自定义守卫的策略import { DOMAspect } from microsoft/fast-element/dom.js; import { DOMPolicy } from microsoft/fast-element/dom-policy.js; import { html, oneWay } from microsoft/fast-element; function sanitizeHTML(value: string): string { // 此处接入应用自己的 HTML 净化器 return value; } const trustedType globalThis.trustedTypes?.createPolicy(app-rich-text, { createHTML(html) { return html; }, }) ?? { createHTML: html html }; const richTextPolicy DOMPolicy.create({ guards: { aspects: { [DOMAspect.property]: { innerHTML: (_tagName, _aspect, _aspectName, sink) { return (target, name, value, ...rest) { const sanitized sanitizeHTML(String(value)); sink(target, name, trustedType.createHTML(sanitized), ...rest); }; }, }, }, }, }); const template htmlMessageView article :innerHTML${oneWay(x x.messageHtml, richTextPolicy)}/article ;这里trustedType.createHTML(sanitized)正是TrustedTypesPolicy.createHTML契约的直接调用确保净化后的 HTML 以可信类型身份写入 DOM。绑定级策略也可以通过html模板的.withPolicy(policy)在编译前为整个模板指定当前仓库的 3.x 进阶文档 dom-policy-and-trusted-types.md 对该模式有完整演示。五、测试验证Trusted Types 策略的运行时行为当前仓库用 Playwright 测试锁定了上述行为可作为理解TrustedTypes实际效果的最直接证据。在 dom-policy.pw.spec.ts 中自定义策略测试测试通过page.addInitScript注入一个名为app-fast-html的createPolicy包装然后DOMPolicy.create({ trustedType: createTrustedType() })创建策略并调用policy.createHTML(Hello world)断言自定义策略的createHTML确实被调用invoked true默认策略名测试测试拦截globalThis.trustedTypes.createPolicy断言创建出来的策略名恰好是[fast-html, fast-html]——这与 dom.ts 中fastTrustedType与 dom-policy.ts 中createTrustedType()的默认命名完全一致从运行时角度验证了TrustedTypes.createPolicy(fast-html, ...)的实际调用链。六、安全使用清单围绕TrustedTypes类型及其配套机制实践建议总结如下全局策略在启动时配置一次通过DOM.setPolicy(DOMPolicy.create({ trustedType }))安装并放在任何组件定义、模板编译之前可复用组件库不应调用DOM.setPolicy()以免抢占宿主应用安装自有策略的机会。CSP 白名单完整为应用创建的每个策略名含依赖默认时的fast-html在trusted-types指令中放行。静态模板视作可信源代码不要用字符串拼接方式把用户输入掺入模板 HTML对动态文本优先使用内容绑定FAST 以textContent渲染不会解析为 HTML。富文本必须净化innerHTML、三括号声明式绑定等 HTML 注入点只能接收已净化内容并配套带innerHTML守卫的策略写入。清楚默认策略的边界默认createHTML不做净化、守卫只覆盖 FAST 绑定写入的 DOM sinkelement.innerHTML ...这类绕过 FAST 的手动赋值不在其保护范围内。七、延伸阅读1.x APITrustedTypes 类型本文主体1.x APITrustedTypesPolicy 类型1.x APIGlobal 类型3.x 进阶DOMPolicy and Trusted Types源码dom.ts · dom-policy.ts · interfaces.ts · debug.ts测试dom-policy.pw.spec.ts赞分享前端UI组件【免费下载链接】fastThe adaptive interface system for modern web experiences.项目地址https://gitcode.com/gh_mirrors/fa/fast点击查看免费下载相关推荐microsoft/fast-element 的 Constructable 类型驱动 FAST 混入类与 DI 体系的构造器类型详解microsoft/fast element 的 Constructable 类型驱动 FAST 混入类与 DI 体系的构造器类型详解 Constructa前端UI组件深入理解 microsoft/fast-element 的 TemplateValue 类型模板插值的统一类型契约深入理解 microsoft/fast element 的 TemplateValue 类型模板插值的统一类型契约 导读 TemplateValue 是前端UI组件深入解析 fast-element 的 ComposableStyles自定义元素 Shadow DOM 的可组合样式类型深入解析 fast element 的 ComposableStyles自定义元素 Shadow DOM 的可组合样式类型 导读 ComposableStyl前端UI组件上一篇Plate 项目 Slate v2 ReactEditor 根窗口辅助 API 恢复实战getWindow / findDocumentOrShadowRoot / hasRange 源码级解析下一篇G-Helper 完整指南如何免费替代 Armoury Crate 控制华硕笔记本创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考