源码湾 源码湾

SingleFile 网页整页存档:55 毫秒存一页,断网双击即开

源码湾
2小时前发布
资源信息 Firefox 临时载入即用,附完整源码。
版本
v1.31.5
授权
AGPL-3.0
体积
2.27 MB
语言
JavaScript
数据库
无
夸克网盘 无提取码 下载

今日下载 0 累计下载 0 还剩 8 个

网页这东西看着像「一篇文章」,其实是一堆外部请求拼起来的。样式在一个 CSS 里,图片在另一个域名上,字体走 CDN,正文还可能是 JS 渲染出来的。所以浏览器自带的「网页另存为」存下来,得到的是一个 html 加一个同名文件夹——文件夹一挪、一改名、一压缩,图片全断。

更麻烦的是分享。那个文件夹压成 zip 发出去,对面解压路径一变,样式表照样 404。想留存的证据、教程、报错现场,过两年就只剩一堆破图。

SingleFile 解决的就是这一步:它把当前页面的 HTML、CSS、图片、字体、框架内容全部抓下来,用 data: URI 内联进一个 HTML 文件。存完只有一个 .html,双击就开,断网也完整。AGPL-3.0,v1.31.5,扩展本体解包 5.12MB。

我拿自建的演示站实测:首页 11 个请求、136,753 字节,存档 55.6 毫秒,产物 180,050 字节,残留外链 0;文章页 7 个请求、48,563 字节,存档 47.5 毫秒,产物 88,121 字节,外链同样 0。把产物用 file:// 打开并拦掉所有 http(s) 请求,联网请求 0 次,图片 8/8 与 4/4 全部解码,JS 报错 0。

有个前提得先说清楚:它出的是 MV2 扩展,Chrome 内核 148 以后装载不上。哪几类人不适合,后面单列。

它和「另存为」差在哪

浏览器自带保存、打印成 PDF、在线剪藏,三条路都有硬伤:

  • 网页另存为:一个 html 加一个资源目录,必须成对存在,移动即坏
  • 打印成 PDF:版式固定成纸面,链接失效、正文不可选中、代码不能复制
  • 在线剪藏:内容传到别人服务器上,服务一停笔记就没了

SingleFile 走的是第四条:把整个页面序列化成一个自包含的 HTML。区别在于三点:

  • 单文件:产物是 1 个 .html,邮件附件、网盘、微信都塞得进去
  • 可搜索:还是 HTML,Ctrl+F 能搜,链接能点,代码块能复制
  • 原样保留结构:页面 DOM 保留,只是把外部资源换成内联,暗色、响应式布局都还在

代价是体积。图片转成 base64 会膨胀约三分之一,实测首页 1.32 倍、文章页 1.81 倍。

我的测试环境

  • Windows:Windows 11,Playwright 自带 Chromium 156.0.8078.4,Node 22.22.2
  • Linux:CentOS Stream 9(kernel 5.14.0-626.el9.x86_64),node 22.22.2 linux-x64
  • 被测页面:自建静态演示站,含外链 CSS/JS、JPEG 与 SVG 图片、懒加载图与内联图标
  • 存档方式:用扩展自带的 lib/single-file.js(与扩展运行时同一份)注入页面后调 getPageData()
  • 验证方式:断网拦请求后统计联网次数、图片解码数、JS 与 console 报错

两个平台的源码包 sha256 都是 1313bea2…1f91d3,是同一份。

装载:两条路

商店安装最省事。Firefox 和 Chrome 都能直接搜到,装完工具栏多一个图标,点一下存当前页,长按能选「存全部标签页」。

离线包适合装不了商店的机器——内网、公司电脑、不想登录账号的环境。包里的扩展目录是 Firefox 的 MV2 构建,加载方式:

  1. 地址栏进 about:debugging#/runtime/this-firefox
  2. 点「临时载入附加组件」
  3. 选扩展目录里的 manifest.json

Firefox 上这样装完能直接用,重启浏览器会掉,重新载入一次即可。Chrome 系不要试,原因写在后面的坑里。

从源码构建也是两条命令

想要自己编译一份,Windows 和 Linux 的命令完全一样:

npm ci
npx rollup -c rollup.config.js

Windows 侧 npm ci 拉 101 个包用了 5.11 秒,rollup 出了 19 个 lib/*.js 用 18.14 秒。Linux 侧冷缓存慢一些:npm ci 78 秒、rollup 42 秒,合计 120 秒。

关键结论是产物可复现:把 19 个文件逐个和发行包里同名文件比 sha256,18 个完全一致;唯一的差异是 single-file-extension-background.js(构建 118,440 字节 / 发行包 118,563 字节,差 123 字节),原因是打包时会注入一个签名服务的 API key,源码里留的是 WOLEET_API_KEY_PLACEHOLDER。

跨平台更彻底:Linux 构建的 19 个文件与 Windows 构建 19/19 sha256 全同(single-file.js = 984156e5…20a6af)。这个项目构建产物与平台无关。

实测数据

同一套页面,两个维度分别记:

  • 首页存档:源页 11 个请求 / 136,753 字节 → 存档 55.6 毫秒 → 180,050 字节
  • 文章页存档:源页 7 个请求 / 48,563 字节 → 存档 47.5 毫秒 → 88,121 字节
  • 体积膨胀:首页 1.32 倍,文章页 1.81 倍
  • 内联 data: URI:首页 10 个,文章页 5 个
  • 残留外链(src/href 还指向 http(s)):首页 0,文章页 0
  • 断网打开:实际联网请求 0 次,页面请求总数 1(只有文档本身)
  • 图片解码:首页 8/8,文章页 4/4
  • 报错:JS 报错 0,console error 0,4xx/5xx 0
  • 构建耗时:Windows 5.11 秒 + 18.14 秒;Linux 78 秒 + 42 秒
  • 打包体积:成品包 2.27MB

存档产物头部会写一行注释:Page saved with SingleFile / url: … / saved date: …,出处和时间都在里面,当证据用很方便。

存档前后长什么样

先看源站,存档前的对照基线:

源站首页 - SingleFile 网页整页存档:55 毫秒存一页,断网双击即开

同一个页面,存档后用 file:// 断网打开:

存档首页 离线打开 - SingleFile 网页整页存档:55 毫秒存一页,断网双击即开

肉眼看不出区别——导航、卡片、渐变、圆角、字号全在。往下一屏滚动,图片也一样。

文章页的对照更明显,源页有表格、代码块和懒加载图:

源站文章页 - SingleFile 网页整页存档:55 毫秒存一页,断网双击即开

存档文章页 离线打开 - SingleFile 网页整页存档:55 毫秒存一页,断网双击即开

表格线、代码块底色、行内代码的等宽字体都保留了。截图里那些图片是真实解码出来的,不是占位框。

手机端也验了一遍(390 宽、DSR 2):

存档首页 手机端 - SingleFile 网页整页存档:55 毫秒存一页,断网双击即开

存档文章页 手机端 - SingleFile 网页整页存档:55 毫秒存一页,断网双击即开

响应式没被破坏,因为存档保留的是原 DOM 和原媒体查询,不是把页面拍成一张图。

一个真实的坑:Chrome 载入不了

我原想把扩展装进 Chromium 截几张弹窗图,用 --load-extension 起浏览器,三个版本挨个试:

Chromium 148.0.7778.96   --load-extension 加载数 = 0
Chromium 151.0.7922.34   加载数 = 0
Chromium 156.0.8078.4    加载数 = 0

进 chrome://extensions 一看,一个扩展都没有,而且不报错,也没有 no-load-error。不报错才是最坑的地方——你以为加载成功了,结果点图标没反应,翻日志也翻不出东西。

原因是这个包 manifest_version 是 2,Chrome 从 137 起移除了 --load-extension,148 之后对 MV2 更是静默不加载。所以:

  • 想用 Chrome / Edge:走商店版,别用离线包
  • 想用离线包:走 Firefox,about:debugging 临时载入

所以本文没有扩展弹窗和设置页的截图——那是包的形态限制,不是我漏截。上面所有存档产物都是用包里自带的引擎跑出来的,引擎文件和扩展运行时是同一份。

第二个坑在服务器侧:在面板终端里 nohup bash build.sh & 跑到 79 秒时 npm 报 signal SIGHUP,整条构建被弃。面板的 Web 终端会挂断后台任务,得用 setsid 脱离会话才稳。

存档文件怎么用

产物就是一个普通 HTML,用法有四种:

  • 双击:默认浏览器打开,断网也行
  • 拖进浏览器:拖到任意标签页即可
  • 发给人:单个文件,微信、邮箱、网盘都能传
  • 归档:扔进笔记库或 NAS,十年后还能打开,因为它不依赖任何外部资源

存多个标签页时,长按工具栏图标选「保存全部标签页」,会生成一个 zip,里面是逐页的单个 HTML。

这几类人适合,这几类不适合

适合:

  • 要留存网页证据、教程、报错现场的人
  • 写文档、做笔记,需要把在线资料落成本地文件的人
  • 内网、离线环境的机器,装不了商店版扩展
  • 想把一堆文章打包带走、又不想丢排版的人

不适合:

  • 只用 Chrome 且不愿意装商店版的人。离线包是 MV2,Chromium 148 起静默不加载
  • 要存视频流的人。它抓的是页面资源,不处理流媒体
  • 需要保留「活链接」的人。存档是完全离线的静态副本,页面更新不会同步
  • 追求最小体积的人。base64 内联必然膨胀,图片多的页面能到 1.8 倍

常见问题

源码获取

建议先转存到自己网盘再下载。手机上打开链接点右下角「保存到网盘」,回头在夸克 App 的「我的网盘」里下载。

实测说明

本文截图全部来自本站实测环境(源码湾 yuanmawan.com),实测版本 SingleFile v1.31.5,许可证 AGPL-3.0。

© 版权声明
THE END
喜欢就支持一下吧
点赞 0 分享 收藏
评论 抢沙发
OωO
取消