navigator.clipboard.read() 读取富文本需先检测浏览器支持与权限状态,再用 DOMParser 安全解析 HTML,按语义白名单保留标签并清洗危险属性、协议与脚本,最终输出安全 HTML 或结构化数据。

直接用 navigator.clipboard.read() 读取富文本本身不难,难点在于后续的语义脱敏——既要保留关键结构(如标题、列表、链接),又要剥离潜在风险(如内联脚本、危险属性、恶意 URL)。这不是简单过滤字符串,而是需要 DOM 解析 + 策略化清洗。
先确认浏览器支持与权限状态
read() 方法在 Safari 中仍不可用,Firefox 需手动开启配置,Chrome/Edge 支持最稳定。必须提前检测并处理降级路径:
- 检查
navigator.clipboard?.read是否存在且为函数 - 调用
navigator.permissions.query({name: 'clipboard-read'})获取当前授权状态(granted/prompt/denied) - 若为
denied,不尝试 read(),改用用户手动粘贴(textarea的paste事件)作为备用入口
读取并识别富文本内容类型
剪贴板可能同时包含 text/plain、text/html、甚至 image/png。需遍历 ClipboardItem 并按 MIME 类型分别处理:
- 优先尝试
item.types.includes('text/html'),有则读取 HTML 片段;没有则退到text/plain - 对
text/html调用item.getType('text/html')得到 Blob,再用FileReader读为字符串 - 避免直接用
innerHTML解析——这会执行 script 标签或触发 CSS 表达式(旧版 IE 风险),应使用DOMParser创建无执行上下文的文档
基于 DOM 的语义化脱敏策略
脱敏不是删光所有标签,而是按语义保留安全子集,移除执行能力与副作用:
- 只允许白名单标签:
p、h1–h6、ul/ol/li、strong/em、a(但需重写href)、br、blockquote -
a标签必须:移除javascript:、vbscript:、data:协议;将外部链接转为rel="noopener noreferrer";可选添加target="_blank" - 禁止所有内联样式(
style属性)、on*事件属性、class(除非你有预设的 CSS 类白名单) - 用
textContent替代innerHTML提取纯文本备选,避免残留 HTML 注入点
输出安全 HTML 或结构化数据
清洗后的 DOM 可序列化为安全 HTML 字符串,也可进一步提取语义结构供业务使用:
- 用
new XMLSerializer().serializeToString(cleanNode)输出 HTML(确保不含 script、iframe 等) - 或构建轻量 AST:例如提取所有标题文字+层级、链接地址+锚文本、列表项数组,供编辑器或预览组件消费
- 若业务允许,可额外注入来源标识(如
<!-- pasted-from-external via clipboard -->),便于审计但不渲染
整个流程依赖用户手势触发、权限许可和 DOM 解析,不复杂但容易忽略权限拒绝后的 fallback 和 HTML 解析的安全上下文隔离。

















