HTML5 Web Storage
摘要:這篇文章會涵蓋 HTML5 Web Storage 的幾個重點觀念,並介紹其基本用法,以及一些該注意的地方(包含一個使用 Visual Studio 2012 來撰寫範例程式的短片)。Web Storage 要點整理
- HTML5 的 Web Storage 是一種可讓網頁將資料儲存於本地端的技術,其作用如同 cookie。
- 儲存於 Web Storage 中的資料,是以 key-value pair 的形式保存(如同 cookie)。
- Cookie 儲存空間很小,最多僅能儲存 4 KB 的資料。HTML5 Web Storage 的儲存空間則大得多,且依各家瀏覽器的實作而不同。一般應該至少有 5 MB 的空間。
- 儲存於 cookie 中的資料會在用戶端瀏覽器與伺服器之間旅行(每次瀏覽器送出 request 至伺服器時就會夾帶 cookies),Web Storage 則不會(純粹運作於用戶端)。這表示 Web Storage 不會占用網路頻寬。
- Web Storage 分為兩種:local storage 和 session storage。細節稍後會說明。
Web Storage 有兩種
Web Storage 分為兩種:local storage 和 session storage。二者的主要差異在於壽命長短與有效範圍。
壽命長短:儲存於 local storage 中的資料,其生命週期較長,session storage 則較短,只要瀏覽器視窗或分頁(tab)關閉就會消失。
有效範圍:儲存於 local storage 的資料可以跨瀏覽器分頁(tab),session storage 則不行。
先知道這樣就好,稍後會進一步說明,並且用一個影片來展示它們的差別。
儲存與讀取
儲存資料的時候,是用 Storage 物件的 setItem 方法。這裡的 Storage 物件,指的是 localStorage 或 sessionStorage,看你想要使用哪一個儲存空間。
範例:
?
1 2 |
window.localStorage.setItem( "MyKeyName" , "MyDataValue" ); window.sessionStorage.setItem( "MyKeyName" , "MyDataValue" ); |
從 Storage 中讀取資料時,則用 getItem 方法:
?
1 2 |
var value1 = window.localStorage.getItem( "MyKeyName" ); var value2 = window.sessionStorage.getItem( "MyKeyName" ); |
在使用 Storage 物件時,前面的 "window" 也可以省略不寫,而且還可以用陣列索引以及屬性的寫法,因此底下的程式片段的每一行作用皆相同:
?
1 2 3 4 |
window.localStorage.setItem( "MyKeyName" , "MyDataValue" ); localStorage.setItem( "MyKeyName" , "MyDataValue" ); localStorage[ "MyKeyName" ] = "Hello" ; localStorage.MyKeyName = "Hello" ; |
儲存在 Web Storage 裡面的資料都可以跨頁面,也就是說,使用者點進去某個網頁之後,先前由上一個網頁所儲存於 Web Storage 的資料,都可以在後續的網頁中取得。
注意:有些瀏覽器可能允許你存入字串之外的型別,但 HTML5 的標準是只能存入字串。
清除
呼叫 removeItem 方法可以移除某一筆資料,例如:
?
1 | localStorage.removeItem( "MyKeyName" ); |
如果要清除 Storage 物件中的全部資料,可用 clear 方法。
實作練習
底下的短片,主要目的是展示 localStorage 和 sessionStorage 的差異。
範例程式碼:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<!DOCTYPE html> <html xmlns= "http://www.w3.org/1999/xhtml" > <head> <title></title> <script src= "Scripts/modernizr-2.5.3.js" type= "text/javascript" ></script> <script type= "text/javascript" > function onLoad() { outputArea.value = window.localStorage.remainingSpace; btnSave.addEventListener( "click" , saveToStorage); btnLoadFromLocalStorage.addEventListener( "click" , loadFromLocalStorage); btnLoadFromSessionStorage.addEventListener( "click" , loadFromSessionStorage); } function saveToStorage() { //window.localStorage.setItem("UserData", inputArea.value); //localStorage.setItem("UserData", inputArea.value); //localStorage["UserData"] = inputArea.value; localStorage.UserData = inputArea.value; sessionStorage.UserData = inputArea.value; } function loadFromLocalStorage() { outputArea.value = localStorage[ "UserData" ]; } function loadFromSessionStorage() { outputArea.value = sessionStorage[ "UserData" ]; } </script> </head> <body onload= "onLoad()" > Input: <textarea id= "inputArea" ></textarea> Output: <textarea id= "outputArea" ></textarea> <button id= "btnSave" >儲存至 local 與 session storage</button> <button id= "btnLoadFromLocalStorage" >從 local storage 載入資料</button> <button id= "btnLoadFromSessionStorage" >從 session storage 載入</button> </body> </html> |
Local Storage vs. Session Storage
經過前面的重點提示以及影片的範例展示,看官應該已經大致了解這種兩儲存空間的差別。這裡再稍微囉嗦一下。
有沒有碰過一種情形:你在 A 網頁選了某些選項或輸入資料,想說先不要 submit 到下一頁,而選擇將此頁再開一個到新視窗,然後在那個新視窗裡面輸入不同的資料,並且 submit 到下一頁,看看會產生甚麼結果。比如說,你可能只是想試試看不同的寄送方式,其運費的差異是多少。於是,你在第一個視窗裡面選了一般掛號,然後在另一個新視窗裡面挑選了快遞。了解價格差異之後,覺得快遞太貴了,還是用掛號就好,於是把選了快遞的那個新視窗關閉,回到你原先的那個視窗繼續操作,可是最後確認交易時,網頁送出的卻是「快遞」。
如果使用 cookie 來保存使用者目前輸入的資料,寫程式時沒有特別注意,就有可能會發生上述情形。這是因為 cookie 會隨著 request 送到伺服器端,然後又隨著 response 送回前端瀏覽器的緣故(於是後來選擇的「快遞」隨著 response 帶回前端又蓋掉了先前儲存的 cookie 值)。在某些應用場合,這種錯誤可能會導致挺嚴重的後果。
Session storage 就可以解決上述問題,因為它的設計就是生命週期短--視窗或分頁關掉就沒了,而且有效範圍窄--資料無法跨分頁,所以無論是開新分頁或新視窗,在先前那個分頁中所儲存於 session storage 中的資料都不會「撈過界」。那麼,網頁 refresh(按 F5)之後,原先儲存在 session storage 中的資料呢?放心,都還在!
注意:有些瀏覽器可能會嘗試延長 session 的壽命。例如當某個分頁掛掉時,使用者選擇重新啟動瀏覽器。有些瀏覽器搞不好會先把這些 session storage 資料保存到暫存檔案,等到重新啟動時再 restore 這些資料。這只能算是特例啦。至於 local storage,應該就很清楚了:適合用於資料需要跨分頁、跨視窗,甚至瀏覽器關掉再開都還要存在的場合。
隔離
此外,瀏覽器會把不同網站的 local storage 隔離開來(session storage 自是不在話下)。意思是,某個網站的網頁所儲存於 local storage 中的資料,其他網站的網頁都看不到。
說得更精確一點,local storage 的資料隔離,係依據「同源策略」。也就是說,只有源自相同網站的網頁才能共享同一塊 local storage。
那麼,怎樣才叫做「相同來源」的網頁呢?就是網址當中的協定、主機名稱、傳輸埠這三者都相同的,即視為相同來源。
注意:不同協定即視為不同來源,所以如果你的網站同時提供 http 和 https,你知道這意味著什麼吧?
注意:不同主機名稱(host name)即視為不同來源,所以相同主機名稱底下的虛擬路徑,是屬於相同來源。補充事項
- 在 HTML5 眾多技術區塊當中,Web Storage 是可以放心使用的,因為現在幾乎所有的瀏覽器都有實作這項功能了(IE 8 也有支援)。
- 雖然 IE 10 有實作 Web Storage 物件的 remainingSpace 屬性,但 Visual Studio 2012 (RC 版)的 HTML 編輯器的 IntelliSense 功能並不會出現提示(如前面的影片中所展示的)。
- Chrome v19.0.x 不支援 remainingSpace 屬性。
最後,Chrome 瀏覽器的「開發人員工具」可以讓你查看、修改、和刪除 Web Storage 資料,參考下圖:
小結
原本只是想用幾個小黑點,重點條列 Web Storage 的幾個特性而已,沒想到寫了這麼落落長,還弄了個影片 XD
不過,還是有些沒提到的地方,例如 Web Storage 的事件處理。
延伸閱讀
- MSDN: Introduction to Web Storage
- The Past, Present & Future Of Local Storage For Web Applications
- 5 Obscure Facts About HTML5 LocalStorage