在漫長的前端開發(fā)過程中,我們常用的幾種本地緩存機(jī)制:Cookie,LocalStorge,SessionStorge
1)cookie的大小受限制,cookie大小被限制在4KB,不能接受像大文件或郵件那樣的大數(shù)據(jù)。
2)只要有請求涉及cookie,cookie就要在服務(wù)器和瀏覽器之間來回傳送(這解釋為什么本地文件不能測試cookie)。而且cookie數(shù)據(jù)始終在同源的http請求中攜帶(即使不需要),這也是Cookie不能太大的重要原因。正統(tǒng)的cookie分發(fā)是通過擴(kuò)展HTTP協(xié)議來實(shí)現(xiàn)的,服務(wù)器通過在HTTP的響應(yīng)頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應(yīng)的cookie。
3)用戶每請求一次服務(wù)器數(shù)據(jù),cookie則會(huì)隨著這些請求發(fā)送到服務(wù)器,服務(wù)器腳本語言如PHP等能夠處理cookie發(fā)送的數(shù)據(jù),可以說是非常方便的。當(dāng)然前端也是可以生成Cookie的,用js對cookie的操作相當(dāng)?shù)姆爆崳瑸g覽器只提供document.cookie這樣一個(gè)對象,對cookie的賦值,獲取都比較麻煩。而在PHP中,我們可以通過setcookie()來設(shè)置cookie,通過$_COOKIE這個(gè)超全局?jǐn)?shù)組來獲取cookie。
說到Cookie就不能不說Session。
Session機(jī)制。session機(jī)制是一種服務(wù)器端的機(jī)制,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來保存信息。當(dāng)程序需要為某個(gè)客戶端的請求創(chuàng)建一個(gè)session時(shí),服務(wù)器首先檢查這個(gè)客戶端的請求里是否已包含了一個(gè)session標(biāo)識(稱為session id),如果已包含則說明以前已經(jīng)為此客戶端創(chuàng)建過session,服務(wù)器就按照session id把這個(gè)session檢索出來使用(檢索不到,會(huì)新建一個(gè)),如果客戶端請求不包含session id,則為此客戶端創(chuàng)建一個(gè)session并且生成一個(gè)與此session相關(guān)聯(lián)的session id,session id的值應(yīng)該是一個(gè)既不會(huì)重復(fù),又不容易被找到規(guī)律以仿造的字符串,這個(gè)session id將被在本次響應(yīng)中返回給客戶端保存。保存這個(gè)session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動(dòng)的按照規(guī)則把這個(gè)標(biāo)識發(fā)送給服務(wù)器。一般這個(gè)cookie的名字都是類似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機(jī)制以便在cookie被禁止時(shí)仍然能夠把session id傳遞回服務(wù)器。經(jīng)常被使用的一種技術(shù)叫做URL重寫,就是把session id直接附加在URL路徑的后面。比如:
http://damonare.cn?sessionid=123456
還有一種技術(shù)叫做表單隱藏字段。就是服務(wù)器會(huì)自動(dòng)修改表單,添加一個(gè)隱藏字段,以便在表單提交時(shí)能夠把session id傳遞回服務(wù)器。比如:
1 2 3 4 | <form name="testform" action="/xxx"> <input type="hidden" name="sessionid" value="123456"> <input type="text"> </form> |
實(shí)際上這種技術(shù)可以簡單的用對action應(yīng)用URL重寫來代替。
Cookie和Session 的區(qū)別:
1)cookie數(shù)據(jù)存放在客戶的瀏覽器上,session數(shù)據(jù)放在服務(wù)器上。
2)cookie不是很安全,別人可以分析存放在本地的cookie并進(jìn)行cookie欺騙,考慮到安全應(yīng)當(dāng)使用session。
3)session會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上。當(dāng)訪問增多,會(huì)比較占用你服務(wù)器的性能考慮到減輕服務(wù)器性能方面,應(yīng)當(dāng)使用cookie。
expires屬性
指定了coolie的生存期,默認(rèn)情況下coolie是暫時(shí)存在的,他們存儲的值只在瀏覽器會(huì)話期間存在,當(dāng)用戶推出瀏覽器后這些值也會(huì)丟失,如果想讓cookie存在一段時(shí)間,就要為expires屬性設(shè)置為未來的一個(gè)過期日期?,F(xiàn)在已經(jīng)被max-age屬性所取代,max-age用秒來設(shè)置cookie的生存期。
path屬性
它指定與cookie關(guān)聯(lián)在一起的網(wǎng)頁。在默認(rèn)的情況下cookie會(huì)與創(chuàng)建它的網(wǎng)頁,該網(wǎng)頁處于同一目錄下的網(wǎng)頁以及與這個(gè)網(wǎng)頁所在目錄下的子目錄下的網(wǎng)頁關(guān)聯(lián)。
domain屬性
domain屬性可以使多個(gè)web服務(wù)器共享cookie。domain屬性的默認(rèn)值是創(chuàng)建cookie的網(wǎng)頁所在服務(wù)器的主機(jī)名。不能將一個(gè)cookie的域設(shè)置成服務(wù)器所在的域之外的域。例如讓位于order.damonare.cn的服務(wù)器能夠讀取catalog.damonare.cn設(shè)置的cookie值。如果catalog.damonare.cn的頁面創(chuàng)建的cookie把自己的path屬性設(shè)置為“/”,把domain屬性設(shè)置成“.damonare.cn”,那么所有位于catalog.damonare.cn的網(wǎng)頁和所有位于orlders.damonare.cn的網(wǎng)頁,以及位于damonare.cn域的其他服務(wù)器上的網(wǎng)頁都可以訪問這個(gè)cookie。
secure屬性
它是一個(gè)布爾值,指定在網(wǎng)絡(luò)上如何傳輸cookie,默認(rèn)是不安全的,通過一個(gè)普通的http連接傳輸
這是一種持久化的存儲方式,也就是說如果不手動(dòng)清除,數(shù)據(jù)就永遠(yuǎn)不會(huì)過期。
它也是采用Key - Value的方式存儲數(shù)據(jù),底層數(shù)據(jù)接口是sqlite,按域名將數(shù)據(jù)分別保存到對應(yīng)數(shù)據(jù)庫文件里。它能保存更大的數(shù)據(jù)(IE8上是10MB,Chrome是5MB),同時(shí)保存的數(shù)據(jù)不會(huì)再發(fā)送給服務(wù)器,避免帶寬浪費(fèi)。
下表是localStorge的一些屬性和方法
屬性方法 | 說明 |
---|---|
localStorage.length | 獲得storage中的個(gè)數(shù) |
localStorage.key(n) | 獲得storage中第n個(gè)元素對的鍵值(第一個(gè)元素是0) |
localStorage.getItem(key) | 獲取鍵值key對應(yīng)的值 |
localStorage.key | 獲取鍵值key對應(yīng)的值 |
localStorage.setItem(key, value) | 添加數(shù)據(jù),鍵值為key,值為value |
localStorage.removeItem(key) | 移除鍵值為key的數(shù)據(jù) |
localStorage.clear() | 清除所有數(shù)據(jù) |
和服務(wù)器端使用的session類似,是一種會(huì)話級別的緩存,關(guān)閉瀏覽器會(huì)數(shù)據(jù)會(huì)被清除。不過有點(diǎn)特別的是它的作用域是窗口級別的,也就是說不同窗口間的sessionStorage數(shù)據(jù)不能共享的。使用方法(和localStorage完全相同):
屬性方法 | 說明 |
---|---|
sessionStorage.length | 獲得storage中的個(gè)數(shù) |
sessionStorage.key(n) | 獲得storage中第n個(gè)元素對的鍵值(第一個(gè)元素是0) |
sessionStorage.getItem(key) | 獲取鍵值key對應(yīng)的值 |
sessionStorage.key | 獲取鍵值key對應(yīng)的值 |
sessionStorage.setItem(key, value) | 添加數(shù)據(jù),鍵值為key,值為value |
sessionStorage.removeItem(key) | 移除鍵值為key的數(shù)據(jù) |
sessionStorage.clear() | 清除所有數(shù)據(jù) |
sessionStorage用于本地存儲一個(gè)會(huì)話(session)中的數(shù)據(jù),這些數(shù)據(jù)只有在同一個(gè)會(huì)話中的頁面才能訪問并且當(dāng)會(huì)話結(jié)束后數(shù)據(jù)也隨之銷毀。因此sessionStorage不是一種持久化的本地存儲,僅僅是會(huì)話級別的存儲。當(dāng)用戶關(guān)閉瀏覽器窗口后,數(shù)據(jù)立馬會(huì)被刪除。
localStorage用于持久化的本地存儲,除非主動(dòng)刪除數(shù)據(jù),否則數(shù)據(jù)是永遠(yuǎn)不會(huì)過期的。第二天、第二周或下一年之后,數(shù)據(jù)依然可用。