kkomelin/isomorphic-dompurify

GitHub: kkomelin/isomorphic-dompurify

为 DOMPurify 提供同构封装,使 HTML 消毒逻辑能在服务端和客户端以统一方式运行。

Stars: 587 | Forks: 16

# 同构 DOMPurify [![npm 版本](https://img.shields.io/npm/v/isomorphic-dompurify.svg)](https://www.npmjs.com/package/isomorphic-dompurify) [![npm 下载量](https://img.shields.io/npm/dw/isomorphic-dompurify)](https://www.npmjs.com/package/isomorphic-dompurify) [![测试状态](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/ef51cb474d075155.svg)](https://github.com/kkomelin/isomorphic-dompurify/actions/workflows/build_test.yml) 该库使得在服务端和客户端上以相同的方式无缝使用 [DOMPurify](https://github.com/cure53/DOMPurify) 成为可能。 除了为 DOMPurify 提供一个同构/通用的包装器外,它本身什么都不做,因此所有功劳都归于 DOMPurify 的作者和贡献者。 - [DOMPurify 演示](https://cure53.de/purify) - [DOMPurify 文档](https://github.com/cure53/DOMPurify/blob/master/README.md) ## 动机 DOMPurify 需要一个 DOM 树才能工作,而 Node 默认不提供 DOM 树。为了在服务端运行,我们需要创建一个虚拟 DOM 并将其提供给 DOMPurify。这意味着服务端和客户端上的 DOMPurify 初始化逻辑是不一样的。 这个项目的诞生是为了封装 DOMPurify 的初始化细节,并提供一种在服务端和客户端(例如在 Next.js 应用中)导入该库的简便方法。 它的灵感来源于 [Isomorphic Unfetch](https://github.com/developit/unfetch/tree/master/packages/isomorphic-unfetch)。 ## 环境要求 | isomorphic-dompurify | Node.js | 环境 | | ------------- | ------------- | ------------- | | `<=0.19.0` | `>=12` | 服务端 | | `>=0.20.0` | `>=14` | 服务端 | | `>=1.4.0` | `>=16` | 服务端 | | `>=1.10.0` | `>=18` | 服务端 | | `>=2.27.0` | `>=20` | 服务端 | | `>=2.30.0` | `>=20.19.5` | 服务端 | | `>=3.0.0` | `^20.19.0 \|\| ^22.12.0 \|\| >=24.0.0` | 服务端 | | `>=3.4.0` | `^20.19.0 \|\| ^22.13.0 \|\| >=24.0.0` | 服务端 | ## 安装 ``` $ npm i isomorphic-dompurify ``` ## 更新 请注意,DOMPurify 库[不遵循语义化版本控制](https://github.com/cure53/DOMPurify/issues/446#issuecomment-643761433),因此我们必须将每项更改作为次要版本发布,因为我们无法 100% 确定 DOMPurify 的补丁版本中是否添加了新功能。 ## 用法 ``` import DOMPurify from "isomorphic-dompurify"; const clean = DOMPurify.sanitize(dirtyString); ``` 你可以将[配置](https://github.com/cure53/DOMPurify/blob/main/README.md)作为第二个参数传递: ``` const clean = DOMPurify.sanitize(dirtyString, { USE_PROFILES: { html: true } }); ``` 同时也支持命名导入: ``` import { sanitize } from "isomorphic-dompurify"; const clean = sanitize(dirtyString); ``` 默认导出也可以作为工厂函数调用,以匹配 `dompurify` 的 API。当你需要将 DOMPurify 实例绑定到特定的 window 时(例如在测试或沙盒环境中),这非常有用: ``` import DOMPurify from "isomorphic-dompurify"; import { JSDOM } from "jsdom"; const purify = DOMPurify(new JSDOM().window); const clean = purify.sanitize(dirtyString); ``` ## TypeScript `dompurify` 中与 hook 相关的类型被重新导出了,因此你可以直接为你的 `addHook` 回调函数指定类型,而无需重新声明函数签名: ``` import { addHook, type NodeHook } from "isomorphic-dompurify"; const stripTargetBlank: NodeHook = function (node) { if ("target" in node) (node as Element).removeAttribute("target"); }; addHook("afterSanitizeAttributes", stripTargetBlank); ``` 可用的类型重导出包括:`Config`, `DOMPurify`, `DocumentFragmentHook`, `ElementHook`, `HookName`, `NodeHook`, `RemovedAttribute`, `RemovedElement`, `UponSanitizeAttributeHook`, `UponSanitizeAttributeHookEvent`, `UponSanitizeElementHook`, `UponSanitizeElementHookEvent`, `WindowLike`。 ## 内存管理(服务端) 在长期运行的 Node.js 进程中,内部的 jsdom window 会在多次清理调用之间累积 DOM 状态,这可能会导致性能逐渐下降和内存增长。请使用 `clearWindow()` 来定期释放这些资源: ``` import { sanitize, clearWindow } from "isomorphic-dompurify"; // Sanitize as usual const clean = sanitize(dirtyString); // Release jsdom resources when appropriate (e.g. after a request, after a batch) clearWindow(); ``` `clearWindow()` 会关闭当前的 jsdom window 并创建一个新的。调用该方法后,所有的导入方式(默认导入和命名导入)都将继续正常工作。 ## Web Worker 支持 `isomorphic-dompurify` 库[与 Web Worker 兼容](https://github.com/kkomelin/isomorphic-dompurify/pull/242), 但是,它所依赖的 `dompurify` [目前还不兼容,至少目前还不行](https://github.com/cure53/DOMPurify/issues/577)。 ## 演练场 想在你最喜欢的框架中尝试 `isomorphic-dompurify` 吗?请查看 [isomorphic-dompurify-playgrounds](https://github.com/kkomelin/isomorphic-dompurify-playgrounds) —— 包含了 Astro、Next.js、Nuxt、React、Svelte 等热门框架的最小化配置示例。 ## 已知问题 - **CommonJS 环境中出现 ERR_REQUIRE_ESM (v3.0.0+):** `jsdom@28` 引入了一个仅支持 ESM 的依赖项,这会在 Vercel 上的 Next.js 等环境中导致 `require()` 失败。临时解决方案是:通过包管理器覆盖配置将 `jsdom` 锁定在 `25.0.1` 版本。详见 [#394](https://github.com/kkomelin/isomorphic-dompurify/issues/394)。 ## 许可证 DOMPurify - [Apache 2.0 或 MPL 2.0](https://github.com/cure53/DOMPurify/blob/master/LICENSE) © 2015 Mario Heiderich Isomorphic DOMPurify - [MIT 许可证](LICENSE) © 2020 [Konstantin Komelin](https://github.com/kkomelin) 及 [贡献者](https://github.com/kkomelin/isomorphic-dompurify/graphs/contributors)
标签:GNU通用公共许可证, HTML过滤, MITM代理, Node.js, Web安全工具库, XSS防御, 同构渲染, 数据可视化, 自动化攻击