[轉貼] Web Storage - 可讓網頁將資料儲存於本地端的技術

2018070810:29
出處:http://huan-lin.blogspot.com/2012/06/html5-web-storage.html
 

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 的事件處理。

延伸閱讀