如何通过Chrome扩展程序保存网页的完整状态?

7

如何保存页面的状态?

例如,考虑用户正在浏览各种网页,其中一些可能编码如下:

onload=function(){
    let d_s = document.getElementById('d').style;
    d_s.width = d_s.height = Math.random() * 500 + 'px';
    setTimeout(onload, 800 + Math.random() * 800);
};
<div id=d style=background:skyblue;></div>
<!-- click Run ↓ -->

我想保存选定选项卡的当前状态(整个选项卡会话),并在将来恢复它们。

有什么技术可以实现这一点?

(这应该是可能的。毕竟,我们可以在播放视频的同时将一个选项卡从一个 Chrome 窗口拖到另一个窗口,而不会发生任何状态更改。)


当你说“当前状态”时,你指的是几个变量的值还是整个页面的状态? - Haibara Ai
2
@HaibaraAi,整个页面。可以将其视为类似于Windows休眠:完全保存和恢复,尽可能少的更改或没有更改。 - Pacerier
Chrome浏览器可以在拖动标签时不中断是因为每个标签都在Chrome内部作为自己的进程运行。没有任何进程处于休眠状态,只是将进程给予一个新的视图(标签)来操作。 - Soviut
浏览器的【后退/前进缓存】似乎正好可以做到这样的快照。 - Sebastian
3个回答

6
简而言之,不行。
这是非常雄心壮志的,因为您不仅需要存储初始DOM状态(该状态可以在任何时候通过加载页面脚本进行更改),还需要存储本地存储、cookie、会话、像图像、脚本、样式表等资源的状态,列表还在继续。
如果您能够低级别地快照内存,将其存储在某个地方,然后稍后将其恢复到内存中,则可能有机会,因为这就是休眠正在执行的操作。但是,在Chrome或任何浏览器中不存在此类API。
即使在任何技术挑战之前,这也将导致您在安装扩展以访问所有各种API时必须请求很多权限。
其次,假设您确实想出了一种序列化页面所有这些方面的方法,那么您将在哪里存储休眠状态?您最好的选择是在后台页面上使用本地存储,但通常有大小限制。
第三,您需要实际浏览页面,以便URL正确设置。没有此步骤,Web页面将仅显示已从休眠中恢复,但如果用户尝试执行任何操作,则会遇到跨站点脚本(XSS)警告,并且刷新页面将返回空白选项卡。
最后,您肯定会遇到几乎无穷无尽的边缘情况,这是由于您无法预测的特定于站点的细微差别而引起的。

关于存储空间,我正在将其保存到本地硬盘(经过许可)。关于DOM状态,是否有办法仅保存初始的DOM状态呢?需要注意的是,我并不打算让它在所有情况下都能正常工作。90%的成功率已经足够了。 - Pacerier
你可以请求 <html> 元素的 innerHtml 并将其存储为一个大字符串。 - Soviut
有哪些技术可以存储“JavaScript状态”(变量)? - Pacerier
你需要递归遍历 window 并祈求一切顺利。现在要么标记我的答案为正确,因为你再也不会得到其他的答案了,要么我很乐意删除它并祈祷没有人再尝试这样做。 - Soviut
@Soviut 如果我有权限的话,我会将其标记为正确的。我也在研究这个主题,希望能找到一些堆快照,然后以二进制形式存储,再以浏览器无关的方式带回来。但是没有。 - King Friday

2

您可以使用selenium来自动化到达所需状态的必要步骤。

通常在测试某些功能时,有人会寻找这样的东西。

我通常在开发一些需要填写大量字段以测试某些相关功能的应用程序时使用它。而且,每次想要测试某些东西时,完成表单真的很繁琐。

使用selenium,您甚至可以自动化整个测试过程。

更新:

如果您需要执行一些js代码,并使用selenium,您可以。

以下是安装了selenium包的Python示例:

>>> from selenium import webdriver
>>> wd = webdriver.Firefox()                   # You could use Chrome too.
>>> wd.get("http://localhost/foo/bar")
>>> wd.execute_script("return foobar()")
u'eli'

此答案中的示例

使用selenium,您可以调用以下函数,并使用一些固定值来模拟保存的状态:

onload=function(){
    /* You could use some fixed value for emulate a saved state */
    let d_s = document.getElementById('d').style;
    d_s.width = d_s.height = some_fixed_value * 500 + 'px';
    setTimeout(onload, 800 + some_fixed_value * 800);
};

但它是否包含其中的JavaScript变量? - Pacerier
我已经更新了答案,并尝试回答你的问题。 - Raydel Miranda

-1

这是HTML5的可怕错误,我们要求作为第三方用户返回第1、2、3页,上一页、下一页、转到... 就像强迫我们通过虚拟机浏览网站。例如,Knowyourmeme应该改变这一点。我只能保存HTML5,但它只是一个状态,不允许我自由更改内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接