Javascript 本地儲存小結

Damonare發表於2016-11-16

前言

總括:詳細講述Cookie,LocalStorge,SesstionStorge的區別和用法。

人生如畫,歲月如歌。

原文部落格地址:Javascript本地儲存小結

知乎專欄&&簡書專題:前端進擊者(知乎)&&前端進擊者(簡書)

1. 各種儲存方案的簡單對比

  • Cookies:瀏覽器均支援,容量為4KB
  • UserData:僅IE支援,容量為64KB
  • Flash:100KB,非HTML原生,需要外掛支援
  • Google Gears SQLite :需要外掛支援,容量無限制
  • LocalStorage:HTML5,容量為5M
  • SesstionStorage:HTML5,容量為5M
  • globalStorage:Firefox獨有的,Firefox13開始就不再支援這個方法

    UserData僅IE支援, Google Gears SQLite需要外掛,Flash已經伴隨著HTML5的出現漸漸退出了歷史舞臺,因此今天我們的主角只有他們三個:Cookie,LocalStorge,SesstionStorge;

2. Cookie

作為一個前端和Cookie打交道的次數肯定不會少了,Cookie算是比較古老的技術了
1993 年,網景公司僱員 Lou Montulli 為了讓使用者在訪問某網站時,進一步提高訪問速度,同時也為了進一步實現個人化網路,發明了今天廣泛使用的 Cookie。

2.1 Cookie的特點

我們先來看下Cookie的特點:

  • 1)cookie的大小受限制,cookie大小被限制在4KB,不能接受像大檔案或郵件那樣的大資料。

  • 2)只要有請求涉及cookie,cookie就要在伺服器和瀏覽器之間來回傳送(這解釋為什麼本地檔案不能測試cookie)。而且cookie資料始終在同源的http請求中攜帶(即使不需要),這也是Cookie不能太大的重要原因。正統的cookie分發是通過擴充套件HTTP協議來實現的,伺服器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。

  • 3)使用者每請求一次伺服器資料,cookie則會隨著這些請求傳送到伺服器,伺服器指令碼語言如PHP等能夠處理cookie傳送的資料,可以說是非常方便的。當然前端也是可以生成Cookie的,用js對cookie的操作相當的繁瑣,瀏覽器只提供document.cookie這樣一個物件,對cookie的賦值,獲取都比較麻煩。而在PHP中,我們可以通過setcookie()來設定cookie,通過$_COOKIE這個超全域性陣列來獲取cookie。

cookie的內容主要包括:名字,值,過期時間,路徑和域。路徑與域一起構成cookie的作用範圍。若不設定過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關閉瀏覽器視窗,cookie就消失。這種生命期為瀏覽器會話期的cookie被稱為會話cookie。會話cookie一般不儲存在硬碟上而是儲存在記憶體裡,當然這種行為並不是規範規定的。若設定了過期時間,瀏覽器就會把cookie儲存到硬碟上,關閉後再次開啟瀏覽器,這些cookie仍然有效直到超過設定的過期時間。儲存在硬碟上的cookie可以在不同的瀏覽器程式間共享,比如兩個IE視窗。而對於儲存在記憶體裡的cookie,不同的瀏覽器有不同的處理方式。

2.2 Session

說到Cookie就不能不說Session。

Session機制。session機制是一種伺服器端的機制,伺服器使用一種類似於雜湊表的結構(也可能就是使用雜湊表)來儲存資訊。當程式需要為某個客戶端的請求建立一個session時,伺服器首先檢查這個客戶端的請求裡是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端建立過session,伺服器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端建立一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字串,這個session id將被在本次響應中返回給客戶端儲存。儲存這個session id的方式可以採用cookie,這樣在互動過程中瀏覽器可以自動的按照規則把這個標識傳送給伺服器。一般這個cookie的名字都是類似於SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞迴伺服器。經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面。比如:http://damonare.cn?sessionid=123456還有一種技術叫做表單隱藏欄位。就是伺服器會自動修改表單,新增一個隱藏欄位,以便在表單提交時能夠把session id傳遞迴伺服器。比如:

複製程式碼

實際上這種技術可以簡單的用對action應用URL重寫來代替。

2.3 Cookie和Session簡單對比

Cookie和Session 的區別:

  • 1)cookie資料存放在客戶的瀏覽器上,session資料放在伺服器上。

  • 2)cookie不是很安全,別人可以分析存放在本地的cookie並進行cookie欺騙,考慮到安全應當使用session。

  • 3)session會在一定時間內儲存在伺服器上。當訪問增多,會比較佔用你伺服器的效能考慮到減輕伺服器效能方面,應當使用cookie。

  • 4)單個cookie儲存的資料不能超過4K,很多瀏覽器都限制一個站點最多儲存20個cookie。
  • 5)所以建議:
    • 將登陸資訊等重要資訊存放為SESSION
    • 其他資訊如果需要保留,可以放在cookie中

2.4 document.cookie的屬性

expires屬性

指定了coolie的生存期,預設情況下coolie是暫時存在的,他們儲存的值只在瀏覽器會話期間存在,當使用者推出瀏覽器後這些值也會丟失,如果想讓cookie存在一段時間,就要為expires屬性設定為未來的一個過期日期。現在已經被max-age屬性所取代,max-age用秒來設定cookie的生存期。

path屬性

它指定與cookie關聯在一起的網頁。在預設的情況下cookie會與建立它的網頁,該網頁處於同一目錄下的網頁以及與這個網頁所在目錄下的子目錄下的網頁關聯。

domain屬性

domain屬性可以使多個web伺服器共享cookie。domain屬性的預設值是建立cookie的網頁所在伺服器的主機名。不能將一個cookie的域設定成伺服器所在的域之外的域。例如讓位於order.damonare.cn的伺服器能夠讀取catalog.damonare.cn設定的cookie值。如果catalog.damonare.cn的頁面建立的cookie把自己的path屬性設定為“/”,把domain屬性設定成“.damonare.cn”,那麼所有位於catalog.damonare.cn的網頁和所有位於orlders.damonare.cn的網頁,以及位於damonare.cn域的其他伺服器上的網頁都可以訪問這個cookie。

secure屬性

它是一個布林值,指定在網路上如何傳輸cookie,預設是不安全的,通過一個普通的http連線傳輸

2.5 cookie實戰

這裡我們使用javascript來寫一段cookie,借用w3cschool的demo:

function getCookie(c_name){
    if (document.cookie.length>0){
        c_start=document.cookie.indexOf(c_name + "=")
        if (c_start!=-1){
            c_start=c_start + c_name.length+1
            c_end=document.cookie.indexOf(";",c_start)
            if (c_end==-1) c_end=document.cookie.length
            return unescape(document.cookie.substring(c_start,c_end))
        }
    }
    return "";
}

function setCookie(c_name,value,expiredays){
    var exdate=new Date()
    exdate.setDate(exdate.getDate()+expiredays)
    document.cookie=c_name+ "=" +escape(value)+
            ((expiredays==null) ? "" : "; expires="+exdate.toUTCString())
}
function checkCookie(){
    username=getCookie('username')
    if(username!=null && username!=""){alert('Welcome again '+username+'!')}
    else{
        username=prompt('Please enter your name:',"")
        if (username!=null && username!=""){
            setCookie('username',username,355)
        }
    }
}複製程式碼

注意這裡對Cookie的生存期進行了定義,也就是355天

3. localStorage

這是一種持久化的儲存方式,也就是說如果不手動清除,資料就永遠不會過期。
它也是採用Key - Value的方式儲存資料,底層資料介面是sqlite,按域名將資料分別儲存到對應資料庫檔案裡。它能儲存更大的資料(IE8上是10MB,Chrome是5MB),同時儲存的資料不會再傳送給伺服器,避免頻寬浪費。

3.1 localStorage的屬性方法

下表是localStorge的一些屬性和方法

屬性方法 說明
localStorage.length 獲得storage中的個數
localStorage.key(n) 獲得storage中第n個元素對的鍵值(第一個元素是0)
localStorage.getItem(key) 獲取鍵值key對應的值
localStorage.key 獲取鍵值key對應的值
localStorage.setItem(key, value) 新增資料,鍵值為key,值為value
localStorage.removeItem(key) 移除鍵值為key的資料
localStorage.clear() 清除所有資料

3.2 localStorage的缺點

  • ① localStorage大小限制在500萬字元左右,各個瀏覽器不一致
  • ② localStorage在隱私模式下不可讀取
  • ③ localStorage本質是在讀寫檔案,資料多的話會比較卡(firefox會一次性將資料匯入記憶體,想想就覺得嚇人啊)
  • ④ localStorage不能被爬蟲爬取,不要用它完全取代URL傳參

4. sessionStorage

和伺服器端使用的session類似,是一種會話級別的快取,關閉瀏覽器會資料會被清除。不過有點特別的是它的作用域是視窗級別的,也就是說不同視窗間的sessionStorage資料不能共享的。使用方法(和localStorage完全相同):

屬性方法 說明
sessionStorage.length 獲得storage中的個數
sessionStorage.key(n) 獲得storage中第n個元素對的鍵值(第一個元素是0)
sessionStorage.getItem(key) 獲取鍵值key對應的值
sessionStorage.key 獲取鍵值key對應的值
sessionStorage.setItem(key, value) 新增資料,鍵值為key,值為value
sessionStorage.removeItem(key) 移除鍵值為key的資料
sessionStorage.clear() 清除所有資料

5. sessionStorage和localStorage的區別

  • sessionStorage用於本地儲存一個會話(session)中的資料,這些資料只有在同一個會話中的頁面才能訪問並且當會話結束後資料也隨之銷燬。因此sessionStorage不是一種持久化的本地儲存,僅僅是會話級別的儲存。當使用者關閉瀏覽器視窗後,資料立馬會被刪除。

  • localStorage用於持久化的本地儲存,除非主動刪除資料,否則資料是永遠不會過期的。第二天、第二週或下一年之後,資料依然可用。

5.1 測試

sessionStorage:

if (sessionStorage.pagecount){
    sessionStorage.pagecount=Number(sessionStorage.pagecount) +1;
}else{
      sessionStorage.pagecount=1;
}
console.log("Visits "+ sessionStorage.pagecount + " time(s).");複製程式碼

測試過程:我們在控制檯輸入上述程式碼檢視列印結果

控制檯首次輸入程式碼:

Javascript 本地儲存小結
sessionStorage測試結果

關閉視窗,控制檯再次輸入程式碼:

Javascript 本地儲存小結
sessionStorage測試結果

所謂的關閉視窗即銷燬,就是這樣,關閉視窗重新開啟輸入程式碼輸出結果還是上面圖片的樣子,也就是說關閉視窗後sessionStorage.pagecount即被銷燬,除非重心建立。或者從歷史記錄進入才會相關資料才會存在。好的,我們再來看下localStorge表現:

if (localStorage.pagecount){
    localStorage.pagecount=Number(localStorage.pagecount) +1;
}else{
    localStorage.pagecount=1;
 }
console.log("Visits "+ localStorage.pagecount + " time(s).");複製程式碼

控制檯首次輸入程式碼:

Javascript 本地儲存小結
localStorage測試結果1

關閉視窗,控制檯再次輸入程式碼:

Javascript 本地儲存小結
localStorage測試結果2

6. web Storage和cookie的區別

Web Storage(localStorage和sessionStorage)的概念和cookie相似,區別是它是為了更大容量儲存設計的。Cookie的大小是受限的,並且每次你請求一個新的頁面的時候Cookie都會被髮送過去,這樣無形中浪費了頻寬,另外cookie還需要指定作用域,不可以跨域呼叫。

除此之外,Web Storage擁有setItem,getItem,removeItem,clear等方法,不像cookie需要前端開發者自己封裝setCookie,getCookie。

但是Cookie也是不可以或缺的:Cookie的作用是與伺服器進行互動,作為HTTP規範的一部分而存在 ,而Web Storage僅僅是為了在本地“儲存”資料而生

後記

博主儘可能思路清晰的理了一遍cookie,session,localStorage,sessionStorage之間的區別和聯絡,希望可以幫到大家。
參考文章:

相關文章