對於瀏覽器來講,一個標籤頁就承載着一個標籤頁會話。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在關閉標籤頁的時候被銷燬了。