五小六 发表于 2024-1-22 21:42:14

前端的那些骚操作

本帖最后由 五小六 于 2024-1-22 21:51 编辑

> 本帖最后由 五小六 于 2024-1-22 21:47 编辑

# SingleFileZ浏览器插件生成离线html的原理

## 背景

之前发布《制作一个属于自己的epub格式电子书》的评论区里有讨论如何更好的保存静态的网页来应对404,朱焱伟推荐SingleFile浏览器插件确实很好用,后面又推荐了一个离线保存体积更小的插件SingleFileZ,很好奇这个插件是怎么实现的,话说这个插件真的是很好用,五星推荐,浏览器的商店或者GitHub都搜得到。

## 原理

插件下载html时会移除里面绝大多数`script`标签并保存图片和字体等资源,采取的应该是base64编码文本,静态html也不需要什么javascript交互只要能很好的展示内容就行。
看看SingleFileZ的简介是怎么描述:

> 将页面保存到自解压式 HTML/ZIP 混合文件中

离线html源码如下图

![截屏2024-01-22 21.49.21.png](data/attachment/forum/202401/22/215109dq0oelhk2uozovfe.png)

离线html的**源码格式**大致如下图
![截屏2024-01-22 20.59.09.png](data/attachment/forum/202401/22/210346atbqm5zaaaaqimo2.png)

展示出的元素的树结构是这样的

![截屏2024-01-22 21.44.48.png](data/attachment/forum/202401/22/214727abpbefyfuve4474v.png)


简单来说就是将一些资源文件压缩为zip并将zip的内容以注释的方式放进html中,在浏览器打开html时先运行`script`标签的脚本获取到注释中zip内容并自解压,解压后的内容大概是html的文本和其他资源,然后通过赋值给innerHTML刷新网页。总之,达到了离线保存网页同时也压缩了文件的体积,还很好的运用的浏览器的算力解压并展示了网页。

## 疑问

如上图4.1中所说`URL: blob:null/1bbda249-d0ba-4415-bfbd-e5d9a67ac58a` 这种应该只是读取了本地的二进制数据,但不明白为什么后台确实有本地的网络请求和成功的状态码。如下图示,确实有很多xhr和fetch请求
![截屏2024-01-22 21.27.06.png](data/attachment/forum/202401/22/213135w9uac8jjln3wz3s8.png)

![截屏2024-01-22 21.27.22.png](data/attachment/forum/202401/22/214125m9194coyco1caf4u.png)

## 感叹

这里真是要感叹作者对html得熟练应用,很巧妙的应用注释标签的功能将一些不符合规则的文件存入html中。

王一之 发表于 2024-1-23 09:47:53

使用 URL.createObjectURL 就可以创建出 blob 的url,至于为什么这样做,难道是为了模拟请求?

五小六 发表于 2024-1-23 14:43:10

王一之 发表于 2024-1-23 09:47
使用 URL.createObjectURL 就可以创建出 blob 的url,至于为什么这样做,难道是为了模拟请求? ...


经过你这么一说我查看了一下展示的元素,是href和src里面直接这么写的。
<link rel="stylesheet" href="blob:null/acc4ed48-a79b-4eba-a874-426cbccabdc2" reportloaderror="">
<img class="rich_pages wxw-img" data-type="png" data-w="36" data-width="100%" style="display:block;vertical-align:inherit;visibility:visible!important;width:100%!important;height:auto!important" data-index="1" src="blob:null/87a6df07-ee56-463c-bc8f-642c6dde1d95" _width="100%" crossorigin="anonymous" alt="图片" data-fail="0">
前端里面的知识点实在太多了,一直都在路上,还是要多讨论,不然我可能就不会往下挖了。

五小六 发表于 2024-1-23 14:53:01

王一之 发表于 2024-1-23 09:47
使用 URL.createObjectURL 就可以创建出 blob 的url,至于为什么这样做,难道是为了模拟请求? ...

刚根据`href="blob:null`搜到一篇文章,虽然没有读懂但是标题说得很清楚。[前端利用Blob对象创建指定文件并下载](https://segmentfault.com/a/1190000015026760) 在离线html的源代码中也找到了`n.content = URL.createObjectURL(new Blob(,{type: t})),`代码,那就应该是利用Blob对象创建图片和字体等文件,这个下载估计就是href或src的请求了。
ggnb

五小六 发表于 2024-3-12 17:13:58

本帖最后由 五小六 于 2024-3-12 17:17 编辑

阅读开发文档是一个很好的习惯,刚发现这些内容作者的文档里都有提及 开发文档的部分节选
页: [1]
查看完整版本: 前端的那些骚操作