对于浏览器来讲,一个标签页就承载着一个标签页会话。html
本文中所讲的session(会话)不是指客户端与服务端之间的会话:web
window.history
就封装了标签页内部的标签页会话模型。
当用户修改标签页的URL,或点击当前页面上的超连接(且<a>
的target attribute为默认值_self
),或提交表单时,就会发生一次文档替换(卸载当前document,加载新的document)。标签页会向会话历史(session history)中增长一个会话历史条目(session history entry)。windows
若是URL的修改只是形成 hashchange(或者经过JavaScript修改了hash),也会增长一个会话历史条目,不过不须要替换文档了。
若是在JavaScript中调用了 history.pushState(),也会增长一个会话历史条目,不过不须要替换文档了。相似地,history.replaceState()
会 修改当前的会话历史条目,不替换文档。
ctrl+shift+t
,用户可以恢复上一次关闭的标签页,以及它承载的会话历史。不过,Back-Forward Cache不会随着它的历史条目一块儿恢复,被恢复的历史条目的文档须要从新加载。Firefox和Safari实现了Back-Forward Cache,在Webkit中它被称为Page Cache。关于它的详细信息能够查看参考资料1和2。我在这里想指出的是,Back-Forward Cache是与标签页会话机制深度结合的:浏览器
unload
或beforeunload
的监听器,其余条件列举在Using Firefox 1.5 caching - Mozilla | MDN),那么旧的文档不会被销毁,而是保留在内存中并暂停其活动。Back-Forward Cache的逻辑是:用户点击前进/后退按钮的时候,就是期待回到“以前看到过的那个页面”,因此浏览器不须要从服务器获取一份新的代码并从新加载页面。缓存
关于Back-Forward Cache的讨论仅仅针对支持它的浏览器(Chrome不支持它)。
<!DOCTYPE html> <!-- test2.html --> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test</title> </head> <body> <a href="./test3.html">link</a> <script> console.log("loading"); // 这行只会在每次从新加载的时候打印 window.addEventListener("pageshow", function (event) { // 这行会在每次从新加载、从缓存中恢复的时候打印 console.log('pageshow', event.persisted, event); }); </script> </body> </html>
<!DOCTYPE html> <!-- test3.html --> <html lang="en"> <head> <meta charset="UTF-8"> <title>Test</title> </head> <body> <a href="./test2.html">link</a> <script> console.log("loading"); // 这行只会在每次从新加载的时候打印 window.addEventListener("pageshow", function (event) { // 这行会在每次从新加载、从缓存中恢复的时候打印 console.log('pageshow', event.persisted, event); }); </script> </body> </html>
步骤(使用Firefox):服务器
<script>
并无被从新执行,而是使用先前的DOM和JavaScript环境。ctrl+shift+t
恢复上次关闭的标签页,验证会话历史条目随着标签页一块儿被恢复了。加载先前的会话历史条目,发现文档没有从缓存中恢复而是从新加载,说明Back-Forward Cache在关闭标签页的时候被销毁了。