【导语】:用浏览器自带的网页另存功能时,经常出现丢失图片,而且还会保存一堆的关联文件。最近 GitHub 上有一个热门开源工具,可以完美解决这些问题。

网页前端项目实践遇到的问题(学习前端编程的同学在借鉴网页源码时老出现丢失保存不完整的问题)(1)

网页源码

简介

SingleFile 是一个浏览器扩展,以及 CLI 工具,可快速将完整的网页保存成单一 HTML 文件。

它兼容 Chrome、Firefox(桌面和移动端)、Edge、Vivaldi、Brave、Waterfox、Yandex 和 Opera 等主流浏览器。

项目地址:

https://github.com/gildas-lormeau/SingleFile

安装

SingleFile 可以安装在:

简单使用

等到页面完全加载后,单击扩展工具栏中的 SingleFile 按钮以保存页面,在处理页面时再次单击该按钮以取消该操作。

SingleFile的命令行界面

SingleFile 可以通过命令行启动,它通过 Node.js 作为注入网页的独立脚本运行。

使用 Docker 安装

docker pull capsulecode/singlefile docker tag capsulecode/singlefile singlefile

git clone --depth 1 --recursive https://github.com/gildas-lormeau/SingleFile.git cd SingleFile/cli docker build --no-cache -t singlefile .

docker run singlefile "https://www.wikipedia.org"

docker run singlefile "https://www.wikipedia.org" > wikipedia.html

手动安装

npm install -g "gildas-lormeau/SingleFile#master"

unzip master.zip . cd SingleFile-master npm install cd cli

git clone --depth 1 --recursive https://github.com/gildas-lormeau/SingleFile.git cd SingleFile npm install cd cli

运行

single-file <url> [output] [options ...]

single-file --help

single-file https://www.wikipedia.org wikipedia.html

single-file --urls-file=list-urls.txt

与用户脚本集成

可以在 SingleFile 保存页面之前或之后执行用户脚本。

  1. 当 SignleFile 作为:
  1. 在用户脚本中分发自定义事件:

dispatchEvent(new CustomEvent("single-file-user-script-init"));

  1. 在用户脚本中监听自定义事件 single-file-on-before-capture-request,这个监听函数会在页面保存前被调用:

addEventListener("single-file-on-before-capture-request", () => { console.log("The page will be saved by SingleFile"); });

  1. 在用户脚本中监听自定义事件 single-file-on-after-capture-request,这个监听函数会在页面保存后被调用:

addEventListener("single-file-on-after-capture-request", () => { console.log("The page has been processed by SingleFile"); });

  1. 例子,这个脚本会在保存页面之前从页面中删除图像,并在处理页面后恢复:

(() => { const elements = new Map(); const removedElementsSelector = "img"; dispatchEvent(new CustomEvent("single-file-user-script-init")); addEventListener("single-file-on-before-capture-request", () => { document.querySelectorAll(removedElementsSelector).forEach(element => { const placeHolderElement = document.createElement(element.tagName); elements.set(placeHolderElement, element); element.parentElement.replaceChild(placeHolderElement, element); }); }); addEventListener("single-file-on-after-capture-request", () => { Array.from(elements).forEach(([placeHolderElement, element]) => { placeHolderElement.parentElement.replaceChild(element, placeHolderElement); }); elements.clear(); }); })();

,