理解瀏覽器的歷史記錄

来源:http://www.cnblogs.com/lyzg/archive/2016/10/11/5941919.html
-Advertisement-
Play Games

這是一篇基礎文章,講述一些瀏覽器裡面歷史記錄棧管理的相關內容。寫這個的起因,源於我最近想研究pushState,看看用它來實現SPA會遇到哪些問題,而pushState最終影響的就是瀏覽器歷史記錄棧裡面的內容,所以就花了點時間琢磨了一下瀏覽器是如何管理歷史記錄棧的。因為在研究的過程中,發現了一些曾經 ...


這是一篇基礎文章,講述一些瀏覽器裡面歷史記錄棧管理的相關內容。寫這個的起因,源於我最近想研究pushState,看看用它來實現SPA會遇到哪些問題,而pushState最終影響的就是瀏覽器歷史記錄棧裡面的內容,所以就花了點時間琢磨了一下瀏覽器是如何管理歷史記錄棧的。因為在研究的過程中,發現了一些曾經不曾註意到一些要點,所以就記錄下來了。

demo地址:http://liuyunzhuge.github.io/blog/history/demo1.html

這個demo用於進行本文後面內容涉及到的相關測試,假如你也感興趣的話,建議每次要測試一個新的問題時,都在新選項卡裡面打開這個demo,而不是從一個已經打開過網頁的選項卡裡面打開;因為已經打開過網頁的選項卡,它的歷史記錄棧裡面已經包含了之前訪問的網頁記錄,所以會對你要測試的問題結果產生影響。

瀏覽器會對同一個視窗(選項卡)中訪問的網頁進行記錄,不管我們是通過以下哪種方式改變網頁,瀏覽器都會把改變後的網頁記錄下來,以便通過瀏覽器的前進和後退按鈕,能夠快速的切換到已經訪問過的網頁:
1)直接在地址欄輸入網頁地址;
2)通過網頁內的超鏈接點擊,跳轉到其它網頁;但是不能是在新視窗中打開的鏈接;
3)通過腳本改變location.href跳轉到其它網頁;
4)通過表單提交跳轉到其它網頁;但是不能是提交到新視窗的表單。
總之,只要是在同一個視窗內,網頁發生了跳轉,瀏覽器都會記錄。不過刷新除外,history對象的length屬性可以查看當前視窗存儲的歷史記錄總數,在前面的demo頁面中,我把這個屬性列印在頁面上,只有網頁改變的時候,這個屬性才會變化;而刷新網頁不會改變這個屬性。

瀏覽器有一個數據結構來存儲網頁的歷史記錄,我把它稱之為歷史記錄棧,因為它的結構跟棧的使用方式有些相似。

操作測試一:假如你複製前面的demo地址,然後在chrome瀏覽器下按以下步驟進行操作:

打開新選項卡;輸入demo1.html;點擊demo2.html;點擊demo3.html;點擊demo4.html;點擊demo3.html;點擊demo2.html;點擊demo1.html。

瀏覽器會以下圖類似的方式來存儲以上的訪問記錄:

image

由於現在的瀏覽器都是多選項卡的模式,當你打開一個選項卡的時候,即使沒有訪問具體網頁,瀏覽器也為這個選項卡創建好了BOM對象,比如history對象,然後把新選項卡的空白頁作為歷史記錄裡面的第一條記錄。所以在上圖中的最後一列可以看到8條記錄,跟demo頁面里顯示的數字一樣:

image

跟歷史記錄棧一起的,瀏覽器還有一個訪問指針來表示當前網頁在歷史記錄棧中的位置。預設情況下,當我們通過前面列舉的方式改變網頁地址的時候,都會把新的頁面壓入到歷史記錄棧的頂部,同時把指針指向到這個最新的網頁,就如上面的圖中所示,每次改變了頁面,當前頁面的指針始終指向的是歷史記錄棧最頂部的那條記錄;當我們通過瀏覽器的前進後退功能(包括按鈕,快捷,右鍵菜單等方式)或者是history提供的go/back/forward方法,都不會改變歷史記錄棧的內容,只會移動一下這個指針:

1)前進功能/go(1)/forward,只是讓這個指針上移1個位置;

2)後退功能/go(-1)/forward,只是讓這個指針下移1個位置;

3)go(n)讓指針上移n個位置;go(-n)讓指針下移n個位置。

瀏覽器根據移動後的指針位置,找到歷史記錄棧中的網頁進行顯示。假如接著操作測試一的結果,繼續做以下操作。

操作測試二:點擊7次瀏覽器後退按鈕。

瀏覽器此時歷史記錄棧的存儲情況就變成下麵這個狀態了:

image

雖然history.go(n)和history.go(-n)可以將指針移動到任意位置,但是當要移動到的位置超出了歷史記錄棧的位置範圍時,指針就不會移動。所以在操作測試二的結果中,調用history.go(-100)和history.go(100)都是不會起作用的。

還有兩種情況會改變歷史記錄棧的內容。

操作測試三:假如我們接著操作測試二的結果,點擊三次前進按鈕,讓瀏覽器的歷史記錄棧進入到下麵這個狀態:

image

此時由於操作測試二和操作測試三都沒有改變歷史記錄棧的內容,所以正確的話,頁面上的歷史記錄統計應該還是8:

image

操作測試四:接著,我們做以下兩步操作:點擊demo2.html,點擊demo3.html。這個時候頁面上的歷史記錄統計變成了:

image

history.length已經改變了,說明歷史記錄棧的內容也變化了。只不過為什麼變成6,而不是10(8+2)呢?看看此時瀏覽器歷史記錄棧的狀態:

image

瀏覽器在往歷史記錄棧裡面壓入新的記錄時,是直接在當前指針後面壓入的,如果當前指針的後面,還有其它的記錄項,都會被丟棄掉。這樣就好理解為啥操作測試四之後的歷史記錄總數只有6個了。

瀏覽器對歷史記錄的管理還有一個要點就是對歷史記錄棧的存儲總數有限制,chrome和firefox都是50。當歷史記錄棧的存儲的量超出這個限制後,歷史記錄的存儲就會採取滾動的方式存儲,也就是新的記錄會壓入到棧的頂部,最底部的記錄會從棧的底部移除出去。通過在demo頁面里,不斷地切換點擊demo1,demo2,demo3,demo4,當達到一定次數的時候,頁面列印的統計信息不再變化,就表示達到歷史記錄達到限制了。不過IE11,我點到100多,發現它還在變化,說明IE的限制可能更高,也可能沒有。。

本文記錄了一些瀏覽器關於歷史記錄管理的內容,可能有分析不到位的地方,歡迎大家的批評與指正。以上內容希望對有需要的朋友加深對history以及pushState的理解有所幫助,謝謝閱讀:)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一 PYTHON 安裝 1. Python下載 (1) www.python.org官網 (2) 選擇可執行文件( 64位3.5.2Windows x86-64 executable installer或32位3.5.2 Windows x86 executable installer)、(64位2 ...
  • 一、簡述 1.對象關係映射文件,用於映射實體類和關係資料庫數據表之間的一個 xml 文件。 2.通過 Entity.hbm.xml 映射文件,Hibernate 可以理解持久化類和數據表之間的對應關係,也可以理解持久化類屬性與數據表列之間的對應關係。 3.映射主鍵、映射關聯關係。 二、各個節點 說明 ...
  • Atitit.java c#.net php項目中的view復用(jsp,aspx,php的復用) 1.1. Keyword1 1.2. 前言1 2. Java項目使用。Net的aspx頁面view1 2.1. Aspx的顯示源碼解決之道1 2.2. Get path n param2 2.3. 還 ...
  • 每天一個設計模式-2 外觀模式(Facade) 1.生活中的示例 客戶想要購買一臺電腦,一般有兩種方法: 1.自己DIY,客戶需要知道組成電腦的所有電子器件,並且需要熟悉那些配件,對客戶要求較高。 2.去電腦組裝公司,告訴他們你需要的電腦配置,再由電腦組裝公司的人來組裝電腦,這種方式比較簡單通用,現 ...
  • 開本系列,談談一些有趣的 CSS 題目,題目類型天馬行空,想到什麼說什麼,不僅為了拓寬一下解決問題的思路,更涉及一些容易忽視的 CSS 細節。 解題不考慮相容性,題目天馬行空,想到什麼說什麼,如果解題中有你感覺到生僻的 CSS 屬性,趕緊去補習一下吧。 不斷更新,不斷更新,不斷更新,重要的事情說三遍 ...
  • textInput綁定目的 textInput綁定主要用於或者元素。他提供了DOM和viewmodel的雙向更新。不同於value綁定,textinput綁定是實時更新的。 例如: Login name: Password: ViewModel: 源碼: Login name: Password: ... ...
  • 「 微信應用號可以做什麼」 簡單說,微信“小程式”可以為開發者提供基於微信的表單、導航、地圖、媒體和位置等開發組件,讓他們在微信的網頁里構建一個 HTML 5 應用。同時微信還開放了登錄和微信支付等介面,讓這個“小程式”可以和用戶的微信賬號打通。 簡單地說,目前微信“錢包”中的“大眾點評”、“京東商 ...
  • 話不投機,話就多,直接上代碼 css代碼: html代碼: <form method="post" id="form_hroizon" enctype="multipart/form-data" action="/"> <input type="hidden" name="phoneTemplet" ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...