理解瀏覽器的歷史記錄

来源: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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...