摘要:數(shù)據(jù)并非存儲(chǔ)在一個(gè)安全環(huán)境中,其中包含的任何數(shù)據(jù)都可以被他人訪問(wèn)。的兩個(gè)主要目標(biāo)是提供一種在之外存儲(chǔ)會(huì)話(huà)數(shù)據(jù)的途徑提供一種存儲(chǔ)大量可以跨會(huì)話(huà)存在的數(shù)據(jù)的機(jī)制。
隨著Web應(yīng)用程序的出現(xiàn),產(chǎn)生了對(duì)于能夠直接在客戶(hù)端上存儲(chǔ)用戶(hù)信息能力的要求。比如登錄信息、偏好設(shè)定或其他數(shù)據(jù),這個(gè)問(wèn)題的第一個(gè)方案是以cookie的形式出現(xiàn)的,今天cookie只是在客戶(hù)端存儲(chǔ)數(shù)據(jù)的其中一種選項(xiàng)。
cookieHTTP Cookie,通常直接叫做cookie,最初是在客戶(hù)端用于存儲(chǔ)會(huì)話(huà)信息的。該標(biāo)準(zhǔn)要求服務(wù)器對(duì)任意HTTP請(qǐng)求發(fā)送Set-Cookie HTTP頭作為響應(yīng)的一部分,其中包含會(huì)話(huà)信息。例如,這種服務(wù)器響應(yīng)的頭可能如下:
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value Other-header: other-header-value
這個(gè)HTTP響應(yīng)設(shè)置以name為名稱(chēng)、以value為值的一個(gè)cookie,名稱(chēng)和值在傳送時(shí)都必須是URL編碼的。瀏覽器會(huì)存儲(chǔ)這樣的會(huì)話(huà)信息,并在這之后,通過(guò)為每個(gè)請(qǐng)求添加Cookie HTTP頭將信息發(fā)送回服務(wù)器,如下所示:
GET /index.html HTTP/1.1 Cookie: name=value Other-header: other-header-value
發(fā)送回服務(wù)器的額外信息可以用于唯一驗(yàn)證客服來(lái)自于發(fā)送的哪個(gè)請(qǐng)求。
限制
cookie在性質(zhì)上是綁定在特定的域名下的。當(dāng)設(shè)定了一個(gè)cookie后,再給創(chuàng)建它的域名發(fā)送請(qǐng)求時(shí),都會(huì)包含這個(gè)cookie。這個(gè)限制確保了存儲(chǔ)在cookie中的信息只能讓批準(zhǔn)的接受者訪問(wèn),而無(wú)法被其他域訪問(wèn)。由于cookie是存在客戶(hù)端計(jì)算機(jī)上的,還加入了一些限制確保cookie不會(huì)被惡意使用,同時(shí)不會(huì)占據(jù)太多磁盤(pán)空間。每個(gè)域的cookie總數(shù)是有限的,不過(guò)瀏覽器之間各有不同。如下所示:
IE6以及更低版本限制每個(gè)域名最多20個(gè)cookie。 IE7和之后版本每個(gè)域名最多50個(gè)。IE7最初是支持每個(gè)域名最大20個(gè)cookie之后被微軟的一個(gè)補(bǔ)丁所更新。 Firefox限制每個(gè)域最多50個(gè)cookie。 Opera限制每個(gè)域最多30個(gè)cookie。 Safari和Chrome對(duì)于每個(gè)域的cookie數(shù)量限制沒(méi)有硬性規(guī)定。
當(dāng)超過(guò)單個(gè)域名限制之后還要再設(shè)置cookie,瀏覽器就會(huì)清除以前設(shè)置的cookie。IE和Opera會(huì)刪除最近最少使用過(guò)的(LRU,Least Recently Used)cookie,騰出空間給新設(shè)置的cookie。Firefox看上去好像是隨機(jī)決定要清除哪個(gè)cookie,所以考慮cookie限制非常重要,以免出現(xiàn)不可預(yù)期的后果。
瀏覽器中對(duì)呀cookie的尺寸也有限制。大多數(shù)瀏覽器都有大約4095B(含4095)以?xún)?nèi)。尺寸限制影響到一個(gè)域下所有的cookie,而并非每個(gè)cookie多帶帶限制。
如果你嘗試創(chuàng)建超過(guò)最大尺寸限制的cookie,那么該cookie會(huì)被悄無(wú)聲息地丟掉。注意,雖然一個(gè)字符通常占用一字節(jié),但是多字節(jié)情況則有所不同。
cookie的構(gòu)成
cookie由瀏覽器保存的以下幾塊信息構(gòu)成。
名稱(chēng):一個(gè)唯一確定cookie的名稱(chēng)。cookie名稱(chēng)是不區(qū)分大小寫(xiě)的,所以myCookie和MyCookie被認(rèn)為是同一個(gè)cookie。然而,實(shí)踐中最好將cookie名稱(chēng)看作是區(qū)分大小寫(xiě)的,因?yàn)槟承┓?wù)器會(huì)這樣處理cookie。cookie的名稱(chēng)必須是經(jīng)過(guò)URL編碼的。 值:儲(chǔ)存在cookie中的字符串值。值必須被URL編碼。 域:cookie對(duì)于哪個(gè)域是有效的。所有向該域發(fā)送的請(qǐng)求中都會(huì)包含這個(gè)cookie信息。這個(gè)值可以包含子域(subdomain,如www.wrox.com),也可以不包含它(如.wrox.com,則對(duì)于wrox.com的所有子域都有效)。如果沒(méi)有明確設(shè)定,那么這個(gè)域會(huì)被認(rèn)作來(lái)自設(shè)置 cookie 的那個(gè)域。 路徑:對(duì)于指定域中的那個(gè)路徑,應(yīng)該向服務(wù)器發(fā)送 cookie。例如,你可以指定 cookie 只有從http://www.wrox.com/books/ 中才能訪問(wèn),那么 http://www.wrox.com 的頁(yè)面就不會(huì)發(fā)送 cookie 信息,即使請(qǐng)求都是來(lái)自同一個(gè)域的。 失效時(shí)間:表示 cookie 何時(shí)應(yīng)該被刪除的時(shí)間戳(也就是,何時(shí)應(yīng)該停止向服務(wù)器發(fā)送這個(gè)cookie)。默認(rèn)情況下,瀏覽器會(huì)話(huà)結(jié)束時(shí)即將所有 cookie 刪除; 不過(guò)也可以自己設(shè)置刪除時(shí)間。這個(gè)值是個(gè) GMT 格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT),用于指定應(yīng)該刪除cookie 的準(zhǔn)確時(shí)間。因此,cookie 可在瀏覽器關(guān)閉后依然保存在用戶(hù)的機(jī)器上。如果你設(shè)置的失效日期是個(gè)以前的時(shí)間,則 cookie 會(huì)被立刻刪除。 安全標(biāo)志:指定后,cookie 只有在使用 SSL 連接的時(shí)候才發(fā)送到服務(wù)器。例如,cookie 信息只能發(fā)送給 https://www.wrox.com,而 http://www.wrox.com 的請(qǐng)求則不能發(fā)送 cookie。
每一段信息都作為 Set-Cookie 頭的一部分,使用分號(hào)加空格分隔每一段,如下例所示。
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com Other-header: other-header-value
該頭信息指定了一個(gè)叫做 name 的 cookie,它會(huì)在格林威治時(shí)間 2007 年 1 月 22 日 7:10:24 失效,同時(shí)對(duì)于 www.wrox.com 和 wrox.com 的任何子域(如 p2p.wrox.com)都有效。
secure 標(biāo)志是 cookie 中唯一一個(gè)非名值對(duì)兒的部分,直接包含一個(gè) secure 單詞。如下: HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value; domain=.wrox.com; path=/; secure Other-header: other-header-value
這里,創(chuàng)建了一個(gè)對(duì)于所有 wrox.com 的子域和域名下(由 path 參數(shù)指定的)所有頁(yè)面都有效的cookie。因?yàn)樵O(shè)置了 secure 標(biāo)志,這個(gè) cookie 只能通過(guò) SSL 連接才能傳輸。
尤其要注意,域、路徑、失效時(shí)間和 secure 標(biāo)志都是服務(wù)器給瀏覽器的指示,以指定何時(shí)應(yīng)該發(fā)送 cookie。這些參數(shù)并不會(huì)作為發(fā)送到服務(wù)器的 cookie 信息的一部分,只有名值對(duì)兒才會(huì)被發(fā)送。
JavaScript 中的 cookie
在JavaScript中處理cookie有些復(fù)雜,因?yàn)槠浔娝苤孽磕_的接口,即BOM的document. cookie屬性。這個(gè)屬性的獨(dú)特之處在于它會(huì)因?yàn)槭褂盟姆绞讲煌憩F(xiàn)出不同的行為。當(dāng)用來(lái)獲取屬性值時(shí),document.cookie 返回當(dāng)前頁(yè)面可用的(根據(jù) cookie 的域、路徑、失效時(shí)間和安全設(shè)置)所有 cookie的字符串,一系列由分號(hào)隔開(kāi)的名值對(duì)兒,如下例所示。
name1=value1;name2=value2;name3=value3
**所有名字和值都是經(jīng)過(guò) URL 編碼的,所以必須使用 decodeURIComponent()來(lái)解碼。
當(dāng)用于設(shè)置值的時(shí)候,document.cookie 屬性可以設(shè)置為一個(gè)新的 cookie 字符串。這個(gè) cookie 字符串會(huì)被解釋并添加到現(xiàn)有的 cookie 集合中。設(shè)置 document.cookie 并不會(huì)覆蓋 cookie,除非設(shè)置的cookie 的名稱(chēng)已經(jīng)存在。設(shè)置 cookie 的格式如下,和 Set-Cookie 頭中使用的格式一樣。**
name=value; expires=expiration_time; path=domain_path; domain=domain_name; secure
這些參數(shù)中,只有 cookie 的名字和值是必需的。下面是一個(gè)簡(jiǎn)單的例子。
document.cookie = "name=Nicholas";
這段代碼創(chuàng)建了一個(gè)叫 name 的 cookie,值為 Nicholas。當(dāng)客戶(hù)端每次向服務(wù)器端發(fā)送請(qǐng)求的時(shí)候,都會(huì)發(fā)送這個(gè) cookie;當(dāng)瀏覽器關(guān)閉的時(shí)候,它就會(huì)被刪除。雖然這段代碼沒(méi)問(wèn)題,但因?yàn)檫@里正好名稱(chēng)和值都無(wú)需編碼,所以最好每次設(shè)置 cookie 時(shí)都像下面這個(gè)例子中一樣使用 encodeURIComponent()。
document.cookie = encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas");
要給被創(chuàng)建的 cookie 指定額外的信息,只要將參數(shù)追加到該字符串,和 Set-Cookie 頭中的格式一樣,如下所示。
document.cookie = encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas") + "; domain=.wrox.com; path=/";
由于 JavaScript 中讀寫(xiě) cookie 不是非常直觀,常常需要寫(xiě)一些函數(shù)來(lái)簡(jiǎn)化 cookie 的功能?;镜腸ookie操作有三種:讀取、寫(xiě)入和刪除。它們?cè)?CookieUtil 對(duì)象中如下表示。
var CookieUtil = { get: function (name) { var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieValue = null; if (cookieStart > -1) { var cookieEnd = document.cookie.indexOf(";", cookieStart); if (cookieEnd == -1){ cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd)); } return cookieValue; }, set: function (name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value); if (expires instanceof Date) { cookieText += "; expires=" + expires.toGMTString(); } if (path) { cookieText += "; path=" + path; } if (domain) { cookieText += "; domain=" + domain; } if (secure) { cookieText += "; secure"; } document.cookie = cookieText; }, unset: function (name, path, domain, secure){ this.set(name, "", new Date(0), path, domain, secure); } }
CookieUtil.get()方法根據(jù) cookie 的名字獲取相應(yīng)的值。它會(huì)在 document.cookie 字符串中查找 cookie 名加上等于號(hào)的位置。如果找到了,那么使用 indexOf()查找該位置之后的第一個(gè)分號(hào)(表示了該 cookie 的結(jié)束位置)。如果沒(méi)有找到分號(hào),則表示該 cookie 是字符串中的最后一個(gè),則余下的字符串都是 cookie 的值。該值使用 decodeURIComponent()進(jìn)行解碼并最后返回。如果沒(méi)有發(fā)現(xiàn) cookie,則返回 null。
CookieUtil.set()方法在頁(yè)面上設(shè)置一個(gè) cookie,接收如下幾個(gè)參數(shù):cookie 的名稱(chēng),cookie 的值,可選的用于指定 cookie 何時(shí)應(yīng)被刪除的 Date 對(duì)象,cookie 的可選的 URL 路徑,可選的域,以及可選的表示是否要添加 secure 標(biāo)志的布爾值。參數(shù)是按照它們的使用頻率排列的,只有頭兩個(gè)是必需的。在這個(gè)方法中,名稱(chēng)和值都使用encodeURIComponent()進(jìn)行了URL編碼,并檢查其他選項(xiàng)。如果expires參數(shù)是 Date 對(duì)象,那么會(huì)使用 Date 對(duì)象的 toGMTString()方法正確格式化 Date 對(duì)象,并添加到expires 選項(xiàng)上。方法的其他部分就是構(gòu)造 cookie 字符串并將其設(shè)置到 document.cookie 中。沒(méi)有刪除已有 cookie 的直接方法。所以,需要使用相同的路徑、域和安全選項(xiàng)再次設(shè)置 cookie,并將失效時(shí)間設(shè)置為過(guò)去的時(shí)間。CookieUtil.unset()方法可以處理這種事情。它接收 4 個(gè)參數(shù):要?jiǎng)h除的 cookie 的名稱(chēng)、可選的路徑參數(shù)、可選的域參數(shù)和可選的安全參數(shù)。這些參數(shù)加上空字符串并設(shè)置失效時(shí)間為 1970 年 1 月 1 日(初始化為 0ms 的 Date 對(duì)象的值),傳給 CookieUtil.set()。這樣就能確保刪除 cookie。可以像下面這樣使用上述方法。
//設(shè)置 cookie CookieUtil.set("name", "Nicholas"); CookieUtil.set("book", "Professional JavaScript"); //讀取 cookie 的值 alert(CookieUtil.get("name")); //"Nicholas" alert(CookieUtil.get("book")); //"Professional JavaScript" //刪除 cookie CookieUtil.unset("name"); CookieUtil.unset("book"); //設(shè)置 cookie,包括它的路徑、域、失效日期 CookieUtil.set("name", "Nicholas", "/books/projs/", "www.wrox.com", new Date("January 1, 2010")); //刪除剛剛設(shè)置的 cookie CookieUtil.unset("name", "/books/projs/", "www.wrox.com"); //設(shè)置安全的 cookie CookieUtil.set("name", "Nicholas", null, null, null, true); CookieExample01.htm
這些方法通過(guò)處理解析、構(gòu)造 cookie 字符串的任務(wù)令在客戶(hù)端利用 cookie 存儲(chǔ)數(shù)據(jù)更加簡(jiǎn)單。
關(guān)于 cookie 的思考
由于所有的 cookie 都會(huì)由瀏覽器作為請(qǐng)求頭發(fā)送,所以在 cookie 中存儲(chǔ)大量信息會(huì)影響到特定域的請(qǐng)求性能。cookie 信息越大,完成對(duì)服務(wù)器請(qǐng)求的時(shí)間也就越長(zhǎng)。盡管瀏覽器對(duì) cookie 進(jìn)行了大小限制,不過(guò)最好還是盡可能在 cookie 中少存儲(chǔ)信息,以避免影響性能。cookie 的性質(zhì)和它的局限使得其并不能作為存儲(chǔ)大量信息的理想手段,所以又出現(xiàn)了其他方法。一定不要在 cookie 中存儲(chǔ)重要和敏感的數(shù)據(jù)。cookie 數(shù)據(jù)并非存儲(chǔ)在一個(gè)安全環(huán)境中,其中包含的任何數(shù)據(jù)都可以被他人訪問(wèn)。所以不要在 cookie 中存儲(chǔ)諸如信用卡號(hào)或者個(gè)人地址之類(lèi)的數(shù)據(jù)。
cookie與session:cookie:存在瀏覽器里,容量有限,不安全(用戶(hù)和瀏覽器都能看到)
1.防篡改 2.加密
session:存在服務(wù)器,容量不用擔(dān)心,安全(用戶(hù)看不到)
session分為兩種:
常用的cookie-session 基于cookie實(shí)現(xiàn)
瀏覽器第一次訪問(wèn)服務(wù)器的時(shí)候,服務(wù)器生成一個(gè)session的id,sess_id,服務(wù)器會(huì)把這個(gè)sess_id作為一個(gè)cookie還給瀏覽器
第二次訪問(wèn)服務(wù)器,瀏覽器帶著cookie訪問(wèn)服務(wù)器,服務(wù)器借助瀏覽器帶的sess_id來(lái)識(shí)別用戶(hù)。
Web Storage 最早是在 Web 超文本應(yīng)用技術(shù)工作組(WHAT-WG)的 Web 應(yīng)用 1.0 規(guī)范中描述的。這個(gè)規(guī)范的最初的工作最終成為了 HTML5 的一部分。Web Storage 的目的是克服由 cookie 帶來(lái)的一些限制,當(dāng)數(shù)據(jù)需要被嚴(yán)格控制在客戶(hù)端上時(shí),無(wú)須持續(xù)地將數(shù)據(jù)發(fā)回服務(wù)器。Web Storage 的兩個(gè)主要目標(biāo)是:
提供一種在 cookie 之外存儲(chǔ)會(huì)話(huà)數(shù)據(jù)的途徑; 提供一種存儲(chǔ)大量可以跨會(huì)話(huà)存在的數(shù)據(jù)的機(jī)制。
**最初的 Web Storage 規(guī)范包含了兩種對(duì)象的定義:sessionStorage 和 globalStorage。這兩個(gè)對(duì)象在支持的瀏覽器中都是以 windows 對(duì)象屬性的形式存在的,支持這兩個(gè)屬性的瀏覽器包括 IE8+、Firefox 3.5+、Chrome 4+和 Opera 10.5+。
Firefox 2 和 3 基于早期規(guī)范的內(nèi)容部分實(shí)現(xiàn)了 Web Storage,當(dāng)時(shí)只實(shí)現(xiàn)了globalStorage,沒(méi)有實(shí)現(xiàn) localStorage。**
Storage 類(lèi)型
Storage 類(lèi)型提供最大的存儲(chǔ)空間(因?yàn)g覽器而異)來(lái)存儲(chǔ)名值對(duì)兒。Storage 的實(shí)例與其他對(duì)象類(lèi)似,有如下方法。
clear(): 刪除所有值;Firefox 中沒(méi)有實(shí)現(xiàn) 。 getItem(name):根據(jù)指定的名字 name 獲取對(duì)應(yīng)的值。 key(index):獲得 index 位置處的值的名字。 removeItem(name):刪除由 name 指定的名值對(duì)兒。 setItem(name, value):為指定的 name 設(shè)置一個(gè)對(duì)應(yīng)的值。
其中,getItem()、removeItem()和 setItem()方法可以直接調(diào)用,也可通過(guò) Storage 對(duì)象間接調(diào)用。因?yàn)槊總€(gè)項(xiàng)目都是作為屬性存儲(chǔ)在該對(duì)象上的,所以可以通過(guò)點(diǎn)語(yǔ)法或者方括號(hào)語(yǔ)法訪問(wèn)屬性來(lái)讀取值,設(shè)置也一樣,或者通過(guò) delete 操作符進(jìn)行刪除。不過(guò),我們還建議讀者使用方法而不是屬性來(lái)訪問(wèn)數(shù)據(jù),以免某個(gè)鍵會(huì)意外重寫(xiě)該對(duì)象上已經(jīng)存在的成員。還可以使用 length 屬性來(lái)判斷有多少名值對(duì)兒存放在 Storage 對(duì)象中。但無(wú)法判斷對(duì)象中所有數(shù)據(jù)的大小,不過(guò) IE8 提供了一個(gè) remainingSpace 屬性,用于獲取還可以使用的存儲(chǔ)空間的字節(jié)數(shù)。Storage 類(lèi)型只能存儲(chǔ)字符串。非字符串的數(shù)據(jù)在存儲(chǔ)之前會(huì)被轉(zhuǎn)換成字符串。
sessionStorage 對(duì)象
sessionStorage 對(duì)象存儲(chǔ)特定于某個(gè)會(huì)話(huà)的數(shù)據(jù),也就是該數(shù)據(jù)只保持到瀏覽器關(guān)閉。這個(gè)對(duì)象就像會(huì)話(huà) cookie,也會(huì)在瀏覽器關(guān)閉后消失。存儲(chǔ)在 sessionStorage 中的數(shù)據(jù)可以跨越頁(yè)面刷新而存在,同時(shí)如果瀏覽器支持,瀏覽器崩潰并重啟之后依然可用(Firefox 和 WebKit 都支持,IE 則不行)。因?yàn)?seesionStorage 對(duì)象綁定于某個(gè)服務(wù)器會(huì)話(huà),所以當(dāng)文件在本地運(yùn)行的時(shí)候是不可用的。存儲(chǔ)在 sessionStorage 中的數(shù)據(jù)只能由最初給對(duì)象存儲(chǔ)數(shù)據(jù)的頁(yè)面訪問(wèn)到,所以對(duì)多頁(yè)面應(yīng)用有限制。
由于 sessionStorage 對(duì)象其實(shí)是 Storage 的一個(gè)實(shí)例,所以可以使用setItem()或者直接設(shè)置新的屬性來(lái)存儲(chǔ)數(shù)據(jù)。下面是這兩種方法的例子。
//使用方法存儲(chǔ)數(shù)據(jù) sessionStorage.setItem("name", "Nicholas"); //使用屬性存儲(chǔ)數(shù)據(jù) sessionStorage.book = "Professional JavaScript";
不同瀏覽器寫(xiě)入數(shù)據(jù)方面略有不同。Firefox 和 WebKit 實(shí)現(xiàn)了同步寫(xiě)入,所以添加到存儲(chǔ)空間中的數(shù)據(jù)是立刻被提交的。而 IE 的實(shí)現(xiàn)則是異步寫(xiě)入數(shù)據(jù),所以在設(shè)置數(shù)據(jù)和將數(shù)據(jù)實(shí)際寫(xiě)入磁盤(pán)之間可能有一些延遲。對(duì)于少量數(shù)據(jù)而言,這個(gè)差異是可以忽略的。對(duì)于大量數(shù)據(jù),你會(huì)發(fā)現(xiàn) IE 要比其他瀏覽器更快地恢復(fù)執(zhí)行,因?yàn)樗鼤?huì)跳過(guò)實(shí)際的磁盤(pán)寫(xiě)入過(guò)程。在 IE8 中可以強(qiáng)制把數(shù)據(jù)寫(xiě)入磁盤(pán):在設(shè)置新數(shù)據(jù)之前使用 begin()方法,并且在所有設(shè)置完成之后調(diào)用 commit()方法。看以下例子。
//只適用于 IE8 sessionStorage.begin(); sessionStorage.name = "Nicholas"; sessionStorage.book = "Professional JavaScript"; sessionStorage.commit();
這段代碼確保了 name 和 book 的值在調(diào)用 commit()之后立刻被寫(xiě)入磁盤(pán)。調(diào)用 begin()是為了確保在這段代碼執(zhí)行的時(shí)候不會(huì)發(fā)生其他磁盤(pán)寫(xiě)入操作。對(duì)于少量數(shù)據(jù)而言,這個(gè)過(guò)程不是必需的;不過(guò),對(duì)于大量數(shù)據(jù)(如文檔之類(lèi)的)可能就要考慮這種事務(wù)形式的方法了。
sessionStorage 中有數(shù)據(jù)時(shí),可以使用 getItem()或者通過(guò)直接訪問(wèn)屬性名來(lái)獲取數(shù)據(jù)。兩種方法的例子如下。
//使用方法讀取數(shù)據(jù) var name = sessionStorage.getItem("name"); //使用屬性讀取數(shù)據(jù) var book = sessionStorage.book;
還可以通過(guò)結(jié)合 length 屬性和 key()方法來(lái)迭代 sessionStorage 中的值,如下所示。
for (var i=0, len = sessionStorage.length; i < len; i++){ var key = sessionStorage.key(i); var value = sessionStorage.getItem(key); alert(key + "=" + value); }
它是這樣遍歷 sessionStorage 中的名值對(duì)兒的:首先通過(guò) key()方法獲取指定位置上的名字,然后再通過(guò) getItem()找出對(duì)應(yīng)該名字的值。還可以使用 for-in 循環(huán)來(lái)迭代 sessionStorage 中的值:
for (var key in sessionStorage){ var value = sessionStorage.getItem(key); alert(key + "=" + value); }
每次經(jīng)過(guò)循環(huán)的時(shí)候,key 被設(shè)置為 sessionStorage 中下一個(gè)名字,此時(shí)不會(huì)返回任何內(nèi)置方法或 length 屬性。
要從 sessionStorage 中刪除數(shù)據(jù),可以使用 delete 操作符刪除對(duì)象屬性,也可調(diào)用removeItem()方法。以下是這些方法的例子。
//使用 delete 刪除一個(gè)值——在 WebKit 中無(wú)效 delete sessionStorage.name; //使用方法刪除一個(gè)值 sessionStorage.removeItem("book");
在撰寫(xiě)本書(shū)時(shí),delete 操作符在 WebKit 中無(wú)法刪除數(shù)據(jù),removeItem()則可以在各種支持的瀏覽器中正確運(yùn)行。
sessionStorage 對(duì)象應(yīng)該主要用于僅針對(duì)會(huì)話(huà)的小段數(shù)據(jù)的存儲(chǔ)。如果需要跨越會(huì)話(huà)存儲(chǔ)數(shù)據(jù),那么 globalStorage 或者 localStorage 更為合適。
localStorage 對(duì)象
由于 localStorage 是 Storage 的實(shí)例,所以可以像使用 sessionStorage 一樣來(lái)使用它。下面是一些例子。
//使用方法存儲(chǔ)數(shù)據(jù) localStorage.setItem("name", "Nicholas"); //使用屬性存儲(chǔ)數(shù)據(jù) localStorage.book = "Professional JavaScript"; //使用方法讀取數(shù)據(jù) var name = localStorage.getItem("name"); //使用屬性讀取數(shù)據(jù) var book = localStorage.book;
存儲(chǔ)在 localStorage 中的數(shù)據(jù)保留到通過(guò) JavaScript 刪除或者是用戶(hù)清除瀏覽器緩存。
為了兼容只支持 globalStorage 的瀏覽器,可以使用以下函數(shù)。
function getLocalStorage(){ if (typeof localStorage == "object"){ return localStorage; } else if (typeof globalStorage == "object"){ return globalStorage[location.host]; } else { throw new Error("Local storage not available."); } }
然后,像下面這樣調(diào)用一次這個(gè)函數(shù),就可以正常地讀寫(xiě)數(shù)據(jù)了。
var storage = getLocalStorage();
在確定了使用哪個(gè) Storage 對(duì)象之后,就能在所有支持 Web Storage 的瀏覽器中使用相同的存取規(guī)則操作數(shù)據(jù)了。
storage 事件
對(duì) Storage 對(duì)象進(jìn)行任何修改,都會(huì)在文檔上觸發(fā) storage 事件。當(dāng)通過(guò)屬性或 setItem()方法保存數(shù)據(jù),使用 delete 操作符或 removeItem()刪除數(shù)據(jù),或者調(diào)用 clear()方法時(shí),都會(huì)發(fā)生該事件。這個(gè)事件的 event 對(duì)象有以下屬性。
domain:發(fā)生變化的存儲(chǔ)空間的域名。 key:設(shè)置或者刪除的鍵名。 newValue:如果是設(shè)置值,則是新值;如果是刪除鍵,則是 null。 oldValue:鍵被更改之前的值。
在這四個(gè)屬性中,IE8 和 Firefox 只實(shí)現(xiàn)了 domain 屬性。在撰寫(xiě)本書(shū)的時(shí)候,WebKit 尚不支持
storage 事件:
以下代碼展示了如何偵聽(tīng) storage 事件:
EventUtil.addHandler(document, "storage", function(event){ alert("Storage changed for " + event.domain); });
無(wú)論對(duì) sessionStorage、globalStorage 還是 localStorage 進(jìn)行操作,都會(huì)觸發(fā) storage事件,但不作區(qū)分。
限制
與其他客戶(hù)端數(shù)據(jù)存儲(chǔ)方案類(lèi)似,Web Storage 同樣也有限制。這些限制因?yàn)g覽器而異。一般來(lái)說(shuō),對(duì)存儲(chǔ)空間大小的限制都是以每個(gè)來(lái)源(協(xié)議、域和端口)為單位的。換句話(huà)說(shuō),每個(gè)來(lái)源都有固定大小的空間用于保存自己的數(shù)據(jù)??紤]到這個(gè)限制,就要注意分析和控制每個(gè)來(lái)源中有多少頁(yè)面需要保存數(shù)據(jù)。
對(duì)于 localStorage 而言,大多數(shù)桌面瀏覽器會(huì)設(shè)置每個(gè)來(lái)源 5MB 的限制。Chrome 和 Safari 對(duì)每個(gè)來(lái)源的限制是 2.5MB。而 iOS 版 Safari 和 Android 版 WebKit 的限制也是 2.5MB。
對(duì) sessionStorage 的限制也是因?yàn)g覽器而異。有的瀏覽器對(duì) sessionStorage 的大小沒(méi)有限制,但 Chrome、Safari、iOS 版 Safari 和 Android 版 WebKit 都有限制,也都是 2.5MB。IE8+和 Opera 對(duì)sessionStorage 的限制是 5MB。
有關(guān) Web Storage 的限制,請(qǐng)參考 http://dev-test.nemikor.com/w...。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103734.html
摘要:平臺(tái)采用分布式存儲(chǔ)系統(tǒng)作為虛擬化存儲(chǔ),用于對(duì)接虛擬化計(jì)算及通用數(shù)據(jù)存儲(chǔ)服務(wù),消除集中式網(wǎng)關(guān),使客戶(hù)端直接與存儲(chǔ)系統(tǒng)進(jìn)行交互,并以多副本糾刪碼多級(jí)故障域數(shù)據(jù)重均衡故障數(shù)據(jù)重建等數(shù)據(jù)保護(hù)機(jī)制,確保數(shù)據(jù)安全性和可用性。云計(jì)算平臺(tái)通過(guò)硬件輔助的虛擬化計(jì)算技術(shù)最大程度上提高資源利用率和業(yè)務(wù)運(yùn)維管理的效率,整體降低 IT 基礎(chǔ)設(shè)施的總擁有成本,并有效提高業(yè)務(wù)服務(wù)的可用性、可靠性及穩(wěn)定性。在解決計(jì)算資源的...
摘要:云存儲(chǔ)主要技術(shù)路線有哪些各有哪些優(yōu)缺點(diǎn)分享一存儲(chǔ)虛擬化存儲(chǔ)虛擬化更多是對(duì)傳統(tǒng)塊的虛擬化。也是云存儲(chǔ)的主流當(dāng)家花旦。哪些應(yīng)用場(chǎng)景適合云存儲(chǔ)?存儲(chǔ)虛擬化、分布式存儲(chǔ)、對(duì)象存儲(chǔ)這幾種技術(shù)主要解決什么問(wèn)題?技術(shù)產(chǎn)品選型如何考慮? 企業(yè)哪些應(yīng)用場(chǎng)景適合借助云存儲(chǔ)來(lái)實(shí)現(xiàn)? 傳統(tǒng) IT 環(huán)境中使用傳統(tǒng)存儲(chǔ)的困境有那些?那些應(yīng)用場(chǎng)景是傳統(tǒng)存儲(chǔ)不能滿(mǎn)足而必須借助云存儲(chǔ)來(lái)實(shí)現(xiàn)的? 分享一: ...
摘要:云存儲(chǔ)主要技術(shù)路線有哪些各有哪些優(yōu)缺點(diǎn)分享一存儲(chǔ)虛擬化存儲(chǔ)虛擬化更多是對(duì)傳統(tǒng)塊的虛擬化。也是云存儲(chǔ)的主流當(dāng)家花旦。 哪些應(yīng)用場(chǎng)景適合云存儲(chǔ)?存儲(chǔ)虛擬化、分布式存儲(chǔ)、對(duì)象存儲(chǔ)這幾種技術(shù)主要解決什么問(wèn)題?技術(shù)產(chǎn)品選型如何考慮?企業(yè)哪些應(yīng)用場(chǎng)景適合借助云存儲(chǔ)來(lái)實(shí)現(xiàn)?傳統(tǒng) IT 環(huán)境中使用傳統(tǒng)存儲(chǔ)的困境有那些?那些應(yīng)...
摘要:采用混合云存儲(chǔ),災(zāi)難恢復(fù)能夠達(dá)到秒級(jí)還是分鐘級(jí)關(guān)鍵還要看帶寬。經(jīng)測(cè)試,采用混合云進(jìn)行分級(jí)存儲(chǔ),在非實(shí)時(shí)高可用場(chǎng)景下,存儲(chǔ)成本可降低在使用歸檔存儲(chǔ)的情況下,成本僅為獨(dú)立建設(shè)災(zāi)備集群的成本的五分之一。人人都說(shuō),混合云/多云是未來(lái)。IDC曾預(yù)測(cè),2018年,85%以上的大型企業(yè)都將采用混合云。RightScale發(fā)布的2018年云計(jì)算調(diào)查報(bào)告也顯示出同樣的趨勢(shì),81%的企業(yè)都有一個(gè)多云策略,其中又...
隨著數(shù)據(jù)量的增長(zhǎng)、數(shù)據(jù)來(lái)源途徑的多元化,企業(yè)用戶(hù)需要考慮到私有云與公有云數(shù)據(jù)存儲(chǔ)的統(tǒng)一性管理,從而隨時(shí)隨地能夠從數(shù)據(jù)存儲(chǔ)平臺(tái)上獲得用戶(hù)所需要的數(shù)據(jù),為業(yè)務(wù)創(chuàng)新帶來(lái)敏捷的數(shù)據(jù)價(jià)值。當(dāng)前行業(yè)用戶(hù)對(duì)混合云的需求越發(fā)明顯,云廠商也是不斷推動(dòng)混合云解決方案在百行百業(yè)中的深入發(fā)展,從而,讓混合云與以軟件定義為主導(dǎo)的存儲(chǔ)顯得越來(lái)越密不可分。因而,就帶來(lái)了一個(gè)重要的混合云治理話(huà)題:混合云架構(gòu)下,如何讓數(shù)據(jù)存儲(chǔ)無(wú)邊...
摘要:對(duì)此,存儲(chǔ)產(chǎn)品經(jīng)理周恭元在月日剛結(jié)束的技術(shù)分論壇上帶來(lái)了海量數(shù)據(jù)云歸檔存儲(chǔ)最佳實(shí)踐的議題分享,圍繞企業(yè)數(shù)據(jù)歸檔面臨的存儲(chǔ)問(wèn)題及需求,重點(diǎn)介紹了數(shù)據(jù)存儲(chǔ)的分層價(jià)值,以及新一代歸檔存儲(chǔ)的可靠性?xún)?yōu)勢(shì)及三大適用場(chǎng)景。隨著互聯(lián)網(wǎng)科技的不斷進(jìn)步,產(chǎn)生的數(shù)據(jù)將以成倍速度進(jìn)行增長(zhǎng),據(jù)IDC預(yù)測(cè),到2025年全球數(shù)據(jù)總量將會(huì)達(dá)到175ZB。如果要把175ZB用8TB的磁盤(pán)存下來(lái)的話(huà),那就需要230億塊磁盤(pán)來(lái)存...
閱讀 2351·2021-11-15 11:38
閱讀 2476·2021-11-15 11:37
閱讀 2579·2021-08-24 10:00
閱讀 2935·2019-08-30 15:56
閱讀 1300·2019-08-30 15:53
閱讀 3737·2019-08-29 18:43
閱讀 2968·2019-08-29 17:01
閱讀 3285·2019-08-29 16:25