第十八章:客戶端存儲

web應用容許使用瀏覽器提供的API實現將數據存儲在用戶電腦上。這種客戶端存儲至關於賦予了web瀏覽器記憶功能。比方說,web應用就能夠用這些方式來「記住」用戶的偏好甚至是用戶的全部狀態信息,以便準確地「回憶」起用戶上一次訪問的位置。客戶端存儲遵循「同源策略」,所以不一樣站點的頁面是沒法讀取對於存儲的數據。而同一站點的不一樣的頁面之間是能夠互相共享存儲數據的,它爲咱們提供了一種通訊機制,例如一個表單的數據能夠顯示在另外一個頁面中。web應用能夠選擇他們存儲數據的有效期:好比採用臨時存儲可讓數據保存至當前窗口關閉或瀏覽器退出;採用永久存儲,能夠將數據永久地存儲在硬盤上,數年或者數月不失效。javascript

客戶端存儲有如下幾種形式:css

web存儲html

web存儲最初做爲HTML5的一部分被定義爲API形式,可是後來被剝離出來做爲獨立的一份標準了。目前包含IE8在內的主流瀏覽器(可交互地)都實現了。web儲存標準所描述的API包含localStorage和sessionStorage對象,這兩個對象其實是持久化的關聯數組,是名值對的映射表,「名」和「值」都是字符串。web存儲易於使用,支持大容量(但非無限量)數據存儲同時兼容當前全部主流瀏覽器(但不兼容早期瀏覽器),本章第一1節會對localStorage和sessionStorage這兩個對象作詳細介紹。java

cookie程序員

cookie是一種早期的客戶端存儲機制,期初是爲徵對服務器端腳本設計使用的。儘管在客戶端提供了很是繁瑣的javascript API來操做cookie,但它們難用至極,並且只適合少許的文本存儲。不只如此,任何以cookie形式存儲的數據,不論服務器端是否須要,每一次HTTP請求都要把這些數據傳輸到服務器端。cookie目前仍然被大量的客戶端程序員使用的一個重要的緣由是:全部新舊瀏覽器都支持它。可是,隨着Web Storage的普及,cookie將最終迴歸到最初的形態:做爲一種被服務端腳本使用的客戶存儲機制。本章第2節將詳細介紹cookie。web

IE User Data正則表達式

微軟在IE5以後的IE瀏覽器實現了專屬它的客戶端存儲機制-「User Data」。userData能夠實現必定量的字符串數據存儲,對於IE8前的IE瀏覽器,能夠將其用作是Web存儲的替代方案。關於userData的API會在本章第3節進行相關的介紹。算法

離線web應用chrome

HTML5標準定義了一組「離線web應用」API,用於緩存web頁面以及相關資源(圖片,腳本,css文件等)。它的現實是將web應用總體存儲在客戶端,而不只是存儲數據。它可以讓web應用「安裝」在客戶端。這樣一來,哪怕網絡不可用的時候web應用依然是可用的。離線web應用的相關內容會在本章第4節介紹。數據庫

web數據庫

爲了可以讓開發者像使用數據那樣操做大量的數據,不少主流瀏覽器紛紛實如今其中開始集成客戶端數據庫功能。Safari,chrome,和opera都內置了SQL數據庫的客戶端API遺憾的是這類的API標準化最終以失敗而了結,而且,Firefox和IE看來不打算實現這類API。目前還有一種正在標準化的API,稱爲「索引數據庫API」。調用該API返回的是一個不包含查詢術語的簡單數據庫對象。這兩種客戶端數據庫API都是異步的,都使用了事件處理機制(相似DOM事件的機制),這樣的方式多多少少都顯得複雜,本章不會對它們作介紹。在20章第8節會簡要介紹全部索引數據庫API同時提供一些例子

文件系統API

在第8章介紹過現代的瀏覽器都支持一個文件對象,用以將選擇的文件經過XMLHttpRequest上傳到服務器。與之相關的規範(草案階段)定義了一組API,用於操做一個私有的本地文件系統。該系統中,能夠進行對文件的讀寫操做。目前正在標準化當中。這些API在20章第7節中作介紹。這些API被普遍地實現和支持,web應用可使用相似文件的存儲機制,這對大部分程序員來講再熟悉不過了。

存儲、安全和隱私

web瀏覽器一般會提供「記住密碼」功能,這些密碼會以加密的形式安全地存儲在硬盤上。然而本章介紹的任何形式客戶端數據存儲都不牽扯加密:任何存儲在用戶硬盤上的數據都是未加密形式。

還要記住一點:不少web用戶不信任那行使用cookie和其它客戶端存儲機制來作相似「跟蹤」功能的網站。因此,儘可能嘗試本章討論的存儲機制來網站升級用戶體驗;而不是用它們來收集和侵犯隱私相關的數據。若是網站濫用客戶端存儲,用戶將禁用該功能。這樣一來不只達不到效果,還會致使依賴客戶端存儲的網站徹底不可用。

 

1.localStorage和sessionStorage

實現了「web存儲」草案標準的瀏覽器在window對象上定義了兩個屬性,localStorage和sessionStorage。這練個屬性表明同一個Storage對象——一個持久化關聯數組,數組使用字符串來索引,存儲的值也是字符串形式的,Storage對象在使用上和通常的javascript沒有什麼兩樣,設置對象的屬性爲字符串值,隨後瀏覽器會將值存儲起來。lcoalStorage和sessionStorage二者的區別在於存儲的有效期和做用域不一樣:數據能夠存儲多長時間及擁有數據的訪問權

下面咱們對存儲的有效期和做用域進行詳細的解釋。不過,再此以前,咱們看些例子,下面的代碼使用的是localStorage,可是它對sessionStorage一樣適用:

            var name = localStorage.username; //查詢一個存儲的值
            name = localStorage["username"]; //等於數組表示法
            if (!name) {
                name = prompt("請輸入你的名字"); //詢問用戶一個答案
                localStorage.username = name; //存儲用戶的答案
            }
            
             //迭代全部存儲的那麼/value對
            for (var name in localStorage) { //迭代全部存儲的名字
                var value = localStorage[name]; //查詢每一個名字對應的值
            }

Storage對象還定義了一些諸如存儲、獲取、遍歷和刪除的方法。這些方法會在第ii小節中介紹。

「web存儲」草案標準指出,咱們既能夠存儲結構話的數據(對象和數組),也能夠存儲原始類型數據,還能夠存儲諸如日期、正則表達式甚至是文件對象在內的內置類型和數據。(在一些瀏覽器中,僅僅支持存儲字符串類型數據,若是要存儲和其它類型的書,不得不本身手動進行和編碼解碼),以下例子所示:

             //當存儲一個數字的時候,會自動轉換成一個字符串
             //可是,當獲取該值的時候,別忘了手動轉換成數字類型
            localStorage.x = 10;
            var x = parseInt(localStorage.x); //
            
            //一樣,存儲一個日期類型數據的時候進行編碼,獲取的時候進行解碼
            localStorage.lastRead = (new Date()).toUTCString();
            var lastdate = new Date(Date.parse(localStorage.lastRead));
            
            
            //使用JSON可使得對基本數據類型的編碼規則變得很方法
            var data = new Date();
            localStorage.data = JSON.stringify(data)//編碼後存儲
            var data = JSON.parse(localStorage.data)//獲取數值後再解碼

 i.存儲有效期和做用域

localStorage和sessionStorage的區別在於存儲的有效期和做用域不一樣經過localStorage存儲的數據是永久性的,除非web應用馬上刪除存儲的數據。或者用戶經過設置瀏覽器配置(瀏覽器提供的特定UI)來刪除,不然數據將一直保留在用戶電腦上,永不過時。

localStorage的做用域是限定在文檔源(document origin)級別的。正如11章6節ii小節描述的,文檔源是經過協議、主機名及端口三者來肯定的。所以,每一個url都有不一樣的文檔源。

        http://www.ahthw.com //協議:http;主機名:www.ahthw.com
        https://www.ahthw.com //不一樣協議
        http://study.ahthw.com //不一樣主機名
        http://www.ahthw.com:8080 //不一樣端口

同源文檔間共享localStorage數據(不論該源的腳本是否真正的訪問的localStorage)。它們能夠互相讀取對方的數據,甚至能夠覆蓋對方的數據。可是,非同源的文檔見互相都不能讀取和共享或覆蓋對方的數據(即便它們的腳原本自同一臺第三方服務器也不行)。

須要注意的是localStorage的做用域也收到瀏覽器供應商的限制。若是你使用的Firefox訪問站點那麼下一次用另一個瀏覽器打開的時候,那麼本次是沒法獲取上次的數據的。

經過sessionStorage存儲的數據和經過localStorage存儲的數據有效期也是不一樣的:sessionStorage的有效期存儲數據的腳本所在最頂層的窗口或者是瀏覽器標籤頁是同樣的。一旦窗口或者標籤頁被永久關閉了,那麼全部經過sessionStorage存儲的數據也被刪除了(須要注意的是,現代的瀏覽器具有了一些關閉標籤頁隨後恢復上一次瀏覽器回話的功能,可能預知相關的sessionStorage會更長些)。

和localStorage同樣,sessionStorage的做用域也是限定在文檔源中,所以,非同源的文檔之間是沒法貢獻sessionStorage的。

須要注意的是:這裏提到的基於窗口做用域的sessionStorage指的窗口是頂級窗口。若是一個瀏覽器標籤包含兩個<iframe>元素,它們是同源的,那麼二者之間是能夠共享的sessionStorage的

ii.存儲API

localStorage和sessionStorage一般是被當作普通的javascript對象使用。經過設置屬性來存儲字符串值,查詢該屬性來讀取該值這兩個對象還提供了兩個正式的API,調用setItem(),將對於的名字和值傳遞進去,能夠實現數據存儲。調用getItem()方法,將名字傳遞進去,能獲取對於的值調用removeItem()方法,將名字傳遞進去,能夠刪除對於的數據。(在非IE8的瀏覽器中,還可使用delete操做符來刪除數據,就和普通對象使用的delete操做符同樣)調用clear()方法(不須要參數),能夠刪除全部存儲的數據。最後,使用length和key()方法,傳入0~length~1的數字,能夠枚舉全部存儲數據的名字。下面是使用localStorage的例子,下面這些代碼對sessionStorage也適用。

            localStorage.setItem("x", 1); //以"x"的名字存儲一個數值
            localStorage.getItem("x"); //獲取x的數值
            
            //枚舉全部的存儲的名字/值對
            for(var i = 0;i<localStorage.length;i++){//length 表示了全部名字/值對
                var name = localStorage.key(i); //獲取第i對的名字
                var value = localStorage.getItem(name);//獲取該對的值
            }
            
            localStorage.removeItem("x")//刪除"x"項
            localStorage.clear();//所有刪除

儘管經過設置和查詢屬性能更加方便地存儲和獲取數據,可是有些時候仍是不得不適應上面所提到的這些方法。比方說其中clear()方法是惟一能刪除存儲對象中的名/值對的方式。一樣的還有,removeItem()是也是惟一經過山粗單個名/值對的方式。(由於IE8不支持delete操做符)

若是瀏覽器提供商徹底實現了「web存儲」的標準,只對對象和數組類型的數據存儲,那麼就會又多了一個使用相似用setItem()和getItem()這類方法的理由。對象和數組的值一般是可變的,所以存儲要也要求存儲它們的副本,以確保以後對任何這類對象的改變不影響到存儲的對象。一樣的 ,在獲取該對象的時候,也要求獲取是該對象的副本,以確保已獲取的對象的改動不會影響到存儲的對象。而這類操做若是若是使用基於屬性的API就會使人困惑。考慮以下這段代碼(假設瀏覽器已經支持告終構化數據存儲)。

        localStorage.o = {x:1};//存儲一個帶有"x"屬性的對象
        localStorage.o.x = 2; //試圖設置該對象的屬性值
        localStorage.o.x; //=>undefined x沒有改變

上述的第二行代碼要設置存儲對象的屬性值,但事實上,它獲取到的只是存儲的對象的副本,隨後設置了該對象的屬性值,而後就將該副本廢棄了。真正的存儲對象保持不變。對於這種狀況,使用getItem()就不會讓人這麼困惑了。

        localStorage.getItem("o").x = 2;//咱們並不像存儲2

另外,還有另一個顯式的機遇存儲API的理由就是:在還不支持「web存儲」標準的瀏覽器中,其它的存儲機制的頂層API對其也是兼容的。下面這段代碼使用cookie和IE userData來實現存儲API。若是使用基層方法的API,當localStorage可用的時候就可使用它編寫代碼,而當它在其它瀏覽器上不可用的時候依然能夠依賴於其它的存儲機制(徹底兼容)。以下代碼所示:

             //識別出是哪類存儲機制
            var memory = window.localStorage || (window.userDataStorage && new userDataStorage()) || new cookieStorage();
             //而後在對於的機制中查詢數據
            var username = memory.getItem("username");

iii.存儲事件

不管何時,存儲在localStorage或者sessionStorage的數據發生改變,瀏覽器都會在其它對該數據可見的窗口對象上出發存儲事件(可是在對數據改變的窗口上是不出發的)。若是瀏覽器有兩個標籤頁都打開了來自於同源的頁面,其中一個在localStorage上存儲了數據,那麼在另一個標籤頁就會接受到一個存儲事件。要記住,sessionStorage的做用域是限制在頂層窗口的,所以對於sessionStorage的改變只有相關牽連的窗口才會觸發存儲事件。像給已經存在的存儲項設置一個如出一轍的值,或者是刪除一個原本就不存在的項存儲都是不會觸發存儲事件的。

爲存儲事件註冊處理程序能夠經過addEventListener()方法,(或者在IE下使用attachEvent方法)。在絕大多瀏覽器中,還能夠給Window對象設置onstorage屬性的方法,不過Firefox不支持該屬性。

與事件相關的事件對象有5個很是重要的屬性(遺憾的是IE8不支持他們)

key

被設置或移除項的鍵名。若是調用clear()函數,那麼該屬性值就爲null.

newValue

保存該項新值;或者調用removeItem()時,該屬性值爲null。

oldvalue

改變或刪除該項前,保存該項的原先值;當插入一個新項的時候,該屬性值爲null

storageArea

這個屬性值就比如目標window對象上的locaStorage屬性或者是sessionStorgae屬性

url

觸發該存儲變化腳本所在的文檔URL

最後,要注意的是:localStorage和sessionStorage存儲機制都是廣播機制的,瀏覽器會對目前正在訪問的同源站點全部窗口發送消息。舉個例子:若是一個用戶要求網站中止動畫效果時,那麼該站點可能會在localStorage中存儲該用戶的首選項,這樣依賴,之後再訪問該站點的時候自動中止該動畫效果了。由於存儲了首選項,致使觸發的一個存儲事件讓其它的同源頁面也得到了一個用戶請求。再好比,一個機遇web的圖片編輯應用,一般容許在其它窗口中展示工具條。當用戶選擇一個工具的時候,應用就可使用localStorage來存儲用戶的當前狀態,而後通知其它的窗口用戶選擇了新的工具。

2.cookie

cookie是指web瀏覽器存儲少許的數據,同時它是與具體的web頁面或者站點相關的。cookie是最先是設計爲被服務端全部的,從底層來看,做爲HTTP協議的一種擴展實現它。cookie數據會自動在web瀏覽器和web服務器之間傳輸的,所以服務端腳本就能夠讀、寫客戶端的cookie值。本書介紹客戶端腳本經過使用Document對象讀取cookie屬性實現cookie的操做。

 爲何叫cookie:「cookie」這個詞沒有太多的含義,可是在計算機歷史上其實很早就用到它了。「cookie」和「magic cookie」用於表明少許數據,特別是指相似密碼這種識別身份或者許可訪問的保密數據。在javascript中,cookie用於保存狀態以及可以爲web瀏覽器提供一種身份識別。可是,javascript中使用cookie不會採起任何加密機制,所以是不安全的。(可是經過https傳說cookie數據是安全的,不過這和cookie自己無關,而和https:協議相關)

操做cookie的api很早就已經定義和實現了,所以次API的兼容性很好。可是,該API的兼容性很好。可是,該API幾乎形同虛設。根本沒有提供諸如查詢、設置、刪除cookie對象的方法,全部這些操做都要經過特殊格式的字符串形式讀寫Document對象的cookie屬性來完成。每一個cookie的有效期和做用域均可以經過cookie屬性分別指定。這些屬性也是經過在同一個cookie上以特殊的字符串來設定的。

本節剩餘的部分會解釋如何經過cookie屬性來指定cookie的有效期和做用域,以及如何經過javascript來設置和查詢cookie值。最後實現一個「基於cookie的存儲api」例子結束本章。

檢測cookie是否可用

用於濫用第三方cookie(如cookie是個網頁上的圖片相關而非網頁自己相關)的緣故,致使cookie在大多數web用戶心中有很差的印象。不少用戶禁用或限制了cookie,所以在師院javascript操做cookie前,首先要確保cookie是啓用的。在絕大多數瀏覽器中,可用通檢測過navigator.cookieEnabled這個屬性來實現,若爲true則代表cookie是啓用的。在不支持該屬性的瀏覽器上,要用下面介紹的cookie技術來讀、寫和刪除cookie數據來測試是否支持cookie。

i.cookie屬性:有效期和做用域

除了名(name)和值(value),cookie還有一些可選的屬性來控制cookie的有效期和做用域。cookie的默認有效期很短暫;它只在持續在web會話期間,一旦關閉瀏覽器,cookie的保存數據就丟失。須要注意的是這與sessionStorage有效期仍是有區別的,cookie的做用域並非限在瀏覽器的單個窗口中,它的有效期和整個瀏覽器進程不是單個瀏覽器窗口的有效期一一致。若是要延長cookie有效期,能夠經過設置max-age屬性,但必需要明確告訴cookie的有效期是多長,單位是秒

一旦設置了有效期,瀏覽器就會將cookie數據存儲在一個文件中,而且知道過了指定的有效期纔會刪除該文件。

和localStorage以及sessionStorage相似,cookie的做用域是經過文檔源和文檔路徑來肯定的該做用域經過cookie的pathdomain屬性配置的。在默認的狀況系啊,cookie和建立它的web頁面有關,並對該web頁面及和該web頁面同目錄或者子目錄其它的頁面可見

好比web頁面http://www.a.com/a/index.html頁面建立了一個cookie,那麼該cookie對http://www.a.com/a/b.html和頁面http://www.a.com/a/b/index.html頁面都是可見的。但對http://www.a.com/c.html是不可見的。

默認的cookie的可見性行爲知足了最多見的需求。不過,有的時候,你可能但願整個網站都使用cookie的值,而無論是那個頁面建立它的。好比用戶在一個頁面表單上輸入了它的郵件地址,你想把它保存下來,爲了避免讓用戶下次回到這個頁面上將其做爲默認的郵件地址。要知足這樣的需求,能夠設置cookie的路徑(設置cookie的path屬性)。

將cookie的路徑設置成"/"等因而讓cookie和localStorage擁有一樣的做用域,同時當它請求該站點上任何一個web頁面的時候,瀏覽器都必須將cookie的名字和值傳遞給服務器。可是須要注意的是,cookie的path屬性不能被用作訪問控制機制。若是一個web頁面想要讀取同一站點其它頁面的cookie,只須要將其餘頁面隱藏<iframe>形式加載進來,隨後讀取對應文檔的cookie就能夠了。同源策略限制了跨站的cookie窺探,可是對同一站點的文檔是徹底合法的

cookie的做用域默認由文檔源限制。可是,有的大型網站想要子域之間可以相互通訊cookie,這個時候就須要設置coolkie的domian屬性來達到目的。若是http://well.a.com的域下建立了一個cookie,並將其path屬性設置成"/",其domian屬性設置成".a.com",那麼這個cookie就對全部good.a.com,other.a.com以及任何其它a.com域下任何其它服務器均可見。若是沒有爲一個cookie設置域屬性,那麼domian屬性的默認值是當前web服務器的主機名。要注意的是,cookie域只能設置當前服務器的域。

最後要介紹的cookie的屬性是secure,它是一個布爾值屬性,用來代表cookie的值是以何種網絡傳輸。cookie默認是以不安全的形式(經過普通的、不安全的HTTP鏈接)傳遞的。一旦cookie被標識爲「安全的」,那就只能當前瀏覽器和服務器經過https或者其它安全協議鏈接的時候才能傳遞它。

ii.保存cookie

要給當前文檔設置有效的cookie值,很是簡單,只需將cookie屬性設置爲一個字符串的形式的值;

name = value;

以下:

document.cookie = "version=" + encodeURIComponent(document.lastModified);

下次讀取cookie屬性的時候,以前存儲的名/值對的數據就在cookie列表中。因爲cookie的名/值中不容許包含分號、逗號和空白符,所以,在存儲以前通常能夠採用javascript核心的全局函數encodeURIComponent()進行編碼。相應的,讀取cookie值的時候須要採用decodeURICompoent()函數解碼

以簡單的名/值對形式存儲的cookie數據有效期只在當前的web瀏覽器會話內,一但用戶關閉瀏覽器,cookie數據就丟失了。若是小要延長cookie的有效期,就須要設置max-age屬性來指定cookie的有效期(單位是秒)。按照下面的字符串形式設置cookie的屬性便可。

name = value; max-age = seconds

下面設置一個cookie值,並提供一個max-age屬性

             //以名/值對形式存儲cookie
             //同時採用encodeURIComponet()函數進行編碼,來轉義分號、逗號和空白符
             //若是dayTolive是一個數字,設置max-age屬性爲該數值表示cookie知道指定的天數
             //到了纔會過時。若是daysTolive是0就表示刪除cookie
            function setcookie(name, value, daysTolive) {
                var cookie = name + "=" + encodeURIComponent(value);
                if (typeof daysTolive === "number")
                    cookie += "; max-age =" + (daysTolive * 60 * 60 * 24);
                document.cookie = cookie;
            }
            setcookie("cook","cool",0);

一樣地,若是要設置cookie的path、domian和secure屬性,只需以下的字符串追加在cookie的值的後面

            ;path = path
            ;domain = domian
            ;secure

要改變cookie的值,須要使用相同的名字、路徑和域,可是新的值從新設置cookie的值。一樣地,設置新max-age屬性就能夠改變cookie的有效期

要刪除一個cookie,須要使用相同的名字、路徑和域,而後制定一個任意(非空)的值,並將max-age屬性指定爲0,再次設置cookie

iii.讀取cookie

使用javascript表達式來讀取cookie屬性的時候,其返回的值是一個字符串,該字符串都是由一系列的名/值對組成,不一樣名/值對之間經過「分號/空格」分開,其內容包含了全部做用在當前文檔的cookie。可是當它不包含其它設置的cookie屬性。經過document.cookie屬性能夠獲取cookie的值,可是爲了更好地查看cookie值,通常會採用split()的方法將cookie值中的名/值對都分離出來

把cookie的值從cookie屬性分離出來以後,必需要採用相應的解碼方式(取決於以前存儲cookie值時的採用的編碼方式),把值還原出來。好比,先採用decodeURIComponent()方法把cookie的值解碼出來,以後再利用JSON.parse()方法轉換成json對象

下面的例子定義了一個getcookie()函數,該函數將document.cookie屬性的值解析出來,將對應的名/值存儲到一個對象中,函數最後返回該對象。

             /**解析document.cookie屬性的值**/
             //將document.cookie的值以名/值對組成一個對象返回
             //假設存儲cookie的值的時候是採用encodeURIComponent()編碼的
            function getcookie() {
                var cookie = {}; //初始化要返回的對象
                var all = document.cookie; //在一個大寫的字符串中獲取全部的cookie值
                if (all === "") //若是cookie爲空字符串
                    return cookie; //返回一個空對象
                var list = all.split(";"); //分離出名/值對
                for (var i = 0; i < list.length; i++) { //遍歷每一個cookie
                    var cookie = list[i];
                    var p = cookie.indexOf("="); //查找第一個"="符號
                    var name = cookie.substring(0, p); //獲取cookie名字
                    var value = cookie.substring(p + 1); //獲取cookie對應的值
                    value = decodeURIComponent(value); //對其值進行解碼
                    cookie[name] = value; //將名/值對存儲到對象中
                }
                return console.log(cookie);
            }

3.利用IE userdata持久化數據

IE以及IE5以上的瀏覽器是經過在document元素後附件一個專屬的"DHTML行爲"來實現客戶端存儲的。以下代碼所示:

            var memory = document.createElement("div"); //建立一個元素
            memory.id = "_memory";
            memory.style.display = "none";
            memory.style.behavior = "url('default#userData')"; //附加userData行爲
            document.body.appendChild(memory); //添加到document元素中

  一旦元素賦予了"userData"行爲,該元素就擁有load()和save()方法。load()方法用於載入存儲的數據。使用它的時候必須傳遞一個字符串做爲參數--相似一個文件名,該參數用來指定要載入的存儲數據。當數據載入後,就能夠經過該元素的屬性來訪問這些名/值對形式的數據,可使用gettAttribute()來查詢攝像數據。經過setAttribute()方法設置屬性。而後調用save()方法能夠存儲新的數據;而要刪除數據,經過使用removeAttribute()方法而後調用save()方法便可。以下所示(該例使用了此前例子中初始化的那個memory元素):

            memory.load("mySoredData"); //根據指定名,載入對於的數據
            var name = memory.getAttribute("username"); //獲取其中數據片斷
            if (!name) { //若是沒有指定的數據片斷
                name = prompt("請輸入"); //
                memory.setAttribute("username", name); //將其設置成memory元素的一個屬性
                memory.save("mySoredData")
            }

默認狀況下,經過userData存儲的數據,除非手動去刪除它不然永不失效。可是,也能夠經過設置expires屬性來指定它的過時時間。就拿上面的例子來講,能夠給存儲的數據設置時長爲100天的有效期,以下所示:

            var now = (new.Date()).getTime(); //獲取當前時間,以毫秒爲單位
            var expires = now + 100 * 24 * 60 * 60 * 1000; //100天的毫秒算法
            expires = new Date(expires).toUTCString(); //將其轉換爲字符串。
            memory.expires = expires; //設置userData的過時時間

IE userData的做用域限制在和當前文檔同目錄的文檔中。它的做用域沒有cookie寬泛,cookie對其所在目錄下的子目錄也有效。userData的機制並無像cookie那樣,經過設置path和domain屬性來控制或改變其做用域的方式。

userData容許存儲的數據量要比cookie大,可是卻比localStorage和sessionStorage容許的存儲量的數據量要小。

下面的例子基於IE的userData實現存儲了API提供的getItem(),setItem()以及removeItem()方法(可是它沒有實現key()或者clear()方法,緣由是userData並無定義遍歷全部存儲項的一種方法

            /**基於IE的userData實現部分存儲的API**/
            function UserDataStorage(maxage){
                //建立一個document元素加載userData行爲
                //所以該元素得到save()和load()方法
                var memory = document.createElement("div"); //建立一個元素
                memory.style.display ="none"; 
                memory.style.behavior = "url('#default#userData')";//附加userData行爲
                document.body.appendChild(memory);//添加到document元素中
                
                //若是傳遞了maxage參數(單位爲秒),則將其設置爲userData的有效期,以毫秒爲單位
                if(maxage){
                    var now = new Date().getTime();//當前時間
                    var expires = now + maxage * 1000;//當前時間加上有效期就等於過時時間
                    memory.expires = new Date(expires).toUTCString();
                }
                
                //經過載入存儲的數據來初始化memory元素
                //參數是任意的,只要是在保存的時候存在就能夠了。
                memory.load("userDataSotrage"); //載入存儲的數據
                
                this.getItem = function(key){//經過屬性來獲取保存的值
                    return memory.getAttribute(key) || null ;
                };
                this.setItem = function(key,value){
                    memory.setAttribute(key,value);//以設置屬性的形式來保存數據
                    memory.save("userDataSotrage"); //保存數據改變後的狀態
                };
                
                this.removeItem = function(key){
                    memory.removeAttribute(key); //刪除存儲的數據
                    memory.save("userDataSotrage"); //再次保存狀態
                };
            }

因爲上述代碼只在IE瀏覽器下有效,最好使用IE條件註釋來避免其餘瀏覽器載入上述代碼。

        <!--[if IE]>
        <script src="userDataStorage.js"></script>
        <![endif]-->

 

(文文未結束,歡迎你們關注上章內容第十七章:jQuery類庫 

3.應用程序存儲和離線web應用

相關文章
相關標籤/搜索