把网页此刻的样子,原样存成一份 HTML。
Save the page as it renders, not as it shipped.
一个 Manifest V3 扩展:点击一次,导出当前页面渲染后的完整 DOM。脚本注入的内容、懒加载的区块、滚动追加的列表,都会一起被保存下来。
安装 · 使用 · 功能一览 · 工作原理 · 权限说明 · 已知限制
浏览器的「另存为」保存的是服务器返回的原始响应,「查看源代码」看到的也是同一份东西。但对今天大多数页面来说,真正的正文是 JavaScript 跑完之后才出现的:React / Vue 渲染出来的结构、滚动到底才加载的评论、点击「展开」才插入的段落——这些在原始响应里一个都找不到。
Save Full HTML 读的是运行时 DOM:
document.documentElement.outerHTML也就是你在开发者工具 Elements 面板里看到的那份结构。页面现在长什么样,存下来就是什么样。
导出结果包含序列化后的 <!DOCTYPE> 与整个 <html> 树,用浏览器直接打开即可复现当时的 DOM。
先让页面加载到你想要的状态(点开「加载更多」、滚动到评论区底部、展开折叠内容),再导出,已插入的内容全部保留。
以 document.title 作为文件名,并清洗掉文件名非法字符(/ \ ? % * : | " < >),避免下载时被浏览器改名或截断。
不请求任何网络权限,不加载远程脚本,不上传统计或页面内容。DOM 在标签页内读出,用 Blob 转成本地下载链接,不经过任何服务器。
只声明 activeTab 与 scripting。前者意味着权限仅在你点击图标的那一刻授予当前标签页,不会常驻访问你浏览的所有网站。没有 service worker,也没有后台常驻进程。
这个扩展没有发布到 Chrome 应用商店,以「加载已解压」的方式安装(适合自己使用或二次改造):
-
克隆仓库:
git clone git@github.com:neotu23/SaveHTML.git
-
打开 Chrome,访问
chrome://extensions/ -
打开右上角的 开发者模式 / Developer mode
-
点击 加载已解压的扩展程序 / Load unpacked,选择
SaveHTML目录 -
在工具栏的拼图菜单里把扩展固定出来,方便随时点击
Edge、Brave、Vivaldi 等 Chromium 内核浏览器的操作步骤一致,入口分别是
edge://extensions/、brave://extensions/等。
- 打开目标网页,等待内容加载完成;如果有「加载更多」,先点开到需要保存的部分
- 点击工具栏中的扩展图标
- 点击 Export HTML
- 文件以页面标题命名,保存到浏览器的默认下载目录
弹出面板下方会显示 Export successful!,失败时显示对应的错误信息。
popup.js 通过 chrome.scripting.executeScript 向当前标签页注入一段函数,读取 DOM,序列化 doctype 并拼到最前面:
const result = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: () => {
let html = document.documentElement.outerHTML;
if (document.doctype) {
html = new XMLSerializer().serializeToString(document.doctype) + '\n' + html;
}
return { html, title: document.title || 'page' };
},
});拿到字符串后用 Blob + URL.createObjectURL 生成临时链接,创建一个 <a download> 元素并 .click(),随后释放 ObjectURL。整个过程只发生在弹出面板的生命周期内,不需要消息通信、不需要 background。
SaveHTML/
├── manifest.json # Manifest V3 配置:权限、图标、popup 入口
├── popup.html # 弹出面板 UI
├── popup.js # 注入脚本抓取 DOM 并触发下载
├── icons/ # 16 / 32 / 48 / 128 px 图标
├── LICENSE
└── README.md
| 权限 | 用途 |
|---|---|
activeTab |
仅在用户点击扩展图标时访问当前标签页 |
scripting |
注入函数以读取页面渲染后的 DOM |
扩展不申请 host_permissions、downloads、storage 或任何远程访问能力。
- 只保存 HTML 结构,不内联图片、CSS、字体和脚本。离线打开时可能丢失样式或图片;如果需要完整归档,请改用 SingleFile 这类会内联资源的方案。
- 跨域 iframe 的内容读不到,受同源策略限制。
- Canvas 绘制的内容、封闭的 Shadow DOM 不会被序列化。
- 受限页面无法注入脚本,例如
chrome://开头的页面、Chrome 应用商店、其他扩展的页面。 - 超长页面一次性序列化后通过 Blob 下载,极端情况下可能占用较多内存。
本项目基于 MIT License 发布。
Copyright © 2026 Neotu