簡述cookie 、localStorage和sessionStorage

Web Storage規(guī)范

是HTML5的一部分

目的:克服由cookie帶來的一些限制,當(dāng)數(shù)據(jù)需要被嚴(yán)格的控制在客戶端時(shí),無須持續(xù)的將數(shù)據(jù)發(fā)回服務(wù)器。

目標(biāo)

  • 提供一種cookie之外的存儲會話數(shù)據(jù)的途徑
  • 提供一種存儲大量可以跨session存在的數(shù)據(jù)的機(jī)制

定義
Web Storage規(guī)范包含兩種對象的定義:sessionStorage和globalStorage**。這兩個(gè)對象在支持的瀏覽器中都是以 window 對象屬性 的形式存在的。
注意:在使用之前記得查看其瀏覽器支持情況

Storage類型

Storage類型的方法:

  • clear(): 刪除所有值
  • getItem(name): 根據(jù)指定的名字 name 獲取對應(yīng)的值
  • setItem(name, value): 為指定的name設(shè)置一個(gè)對應(yīng)的值
  • key(index):獲得index位置處的值的名字。
  • removeItem(name):刪除name指定的鍵值對。
    還可以通過length屬性來判斷有多少鍵值對存放在Storage對象中

注意: Storage類型只能存儲字符串。非字符串的數(shù)據(jù)在存儲之前會被轉(zhuǎn)換為字符串

sessionStorage對象

sessionStorage 對象是存儲特定于某個(gè)會話的數(shù)據(jù),當(dāng)頁面被重新加載時(shí)其仍然存在,只有當(dāng)瀏覽器被關(guān)閉或者當(dāng)前頁面被關(guān)閉時(shí),數(shù)據(jù)才會被清除;可以理解為數(shù)據(jù)被存儲在瀏覽器中,只有瀏覽器被關(guān)閉后,數(shù)據(jù)才會被清除,同時(shí),如果瀏覽器支持,在瀏覽器崩潰并重啟之后仍然可以訪問存儲與sessionStorage中的數(shù)據(jù)

因?yàn)閟essionStorage對象綁定于某個(gè)服務(wù)器會話,所以當(dāng)文件在本地運(yùn)行的時(shí)候是不可用的。

存儲在sessionStorage中的數(shù)據(jù)只能由最初給對象存儲數(shù)據(jù)的頁面訪問到,其只針對于當(dāng)前會話,所以對多頁面應(yīng)用有限制

使用
sessionStorage對象是Storage的一個(gè)實(shí)例,所以可以使用setItem()或者直接設(shè)置新的屬性存儲數(shù)據(jù)
如:

// 使用方法存儲數(shù)據(jù)
sessionStorage.setItem('name', 'Hexon');
// 使用屬性存儲數(shù)據(jù)
sessionStorage.book = 'Professional Javascript'; 

// 使用方法讀取數(shù)據(jù)
var name = sessionStorage.getItem('name');
// 使用方法讀取數(shù)據(jù)
var book = sessionStorage.book;

// 通過key來迭代存儲與sessionStorage中的鍵值
for (var i = 0, len = sessionStorage.length; i < len; i++) {
  var key = sessionStorage.key(i);
  var value = sessionStorage.getItem(key);
  alert(key + '=' + value);
}

// 使用for-in循環(huán)迭代sessionStorage中的值
for (var key in sessionStorage) {
  val value = sessionstorage.getItem(key);
  alert(key + '=' + value);

不同的瀏覽器寫入數(shù)據(jù)方面略有不同,F(xiàn)ireFox和WebKit實(shí)現(xiàn)了同步寫入,所以添加到存儲空間中的數(shù)據(jù)是立刻被提交的。而IE的實(shí)現(xiàn)是異步寫入數(shù)據(jù),在設(shè)置數(shù)據(jù)和將數(shù)據(jù)寫入磁盤之間可能有延遲

總結(jié):sessionStorage對象應(yīng)該只用于針對會話小段數(shù)據(jù)存儲。如果需要跨會話存儲數(shù)據(jù),那么localStorage或者globalStorage更合適

globalStorage對象

只用FireFox2中實(shí)現(xiàn)了globalStorage對象,主要目的是為了實(shí)現(xiàn) 跨會話存儲數(shù)據(jù),但有特定的訪問限制。

要使用globalStorage,首先要指定哪些域名可以訪問該數(shù)據(jù)

使用方法

// 只針對 域名 wrox.com 的存儲訪問
globalStorage['wrox.com'].name = 'hexon';
var name = globaleStorage['wrox.com'].name;

注意:

  • globalStorage對象不是Storage的實(shí)例,而具體的globalStorage['wrox.com'] 才是
  • 當(dāng)使用 globalStorage[''].name = 'hexon'來存儲數(shù)據(jù)時(shí),表示任何人都可以訪問,一定不要這樣做,不安全
  • 對globalStorage空間的訪問,是依據(jù)發(fā)起請求的頁面的域名、協(xié)議和端口 來限制的;如使用https協(xié)議在wrox.com中存儲了數(shù)據(jù),那么通過http訪問的wrox.com的頁面將無法訪問該數(shù)據(jù)
  • 如果事先無法確定域名,那么使用 location.host 作為屬性名比較安全,表示頁面必須來自于同一個(gè)域名、協(xié)議和端口,才可以訪問
  • 如果不使用removeItem() 或者 delete 刪除,或者用戶未清除瀏覽器緩存,存儲在globalStorage屬性中的數(shù)據(jù)將會一直保存在磁盤上

注意: globalStorage對象在修訂過的HTML5規(guī)范中被localStorage對象所取代

localStorage 對象

localStorage對象在修訂過的HTML5規(guī)范中作為持久保存客戶端數(shù)據(jù)的方案取代了globalStorage

與globalStorage不同,不能給localStorage指定規(guī)則,規(guī)則在HTML5規(guī)范中就被制定,要訪問同一個(gè)localStorage對象,頁面必須來自同一個(gè)域名(子域名無效)、同一種協(xié)議,在同一端口上,這相當(dāng)于 globalStorage[location.host]

localStorage是Storage類型的實(shí)例,因此可以像使用sessionStorage一樣使用它

同時(shí), 為了兼容只支持globalStorage對象的瀏覽器,可以使用以下方式進(jìn)行能力檢測:

function getLocalStorage() {
  if (tpyeof localStorage === 'object') {
     return localStorage;
  } else if (typeof globalStorage === 'object') {
     return globalStorage[location.host];
  }  else {
     throw new Error('Local Storage not available.');
  }
}

sessionStorage和localStorage的對比與使用

概念

這兩者都是本地存儲,均不會被發(fā)送到服務(wù)器端,其主要在生命周期上有比較明顯的區(qū)別;localStorage的生命周期更長,沒有過期時(shí)間,原則上要等到通過JavaScript將內(nèi)容清除掉或者清空cookie時(shí)才會消失;而sessionStorage則在Browser或Tab被關(guān)閉時(shí)就會清空

限制

  • 對于localStorage而言,大多數(shù)桌面瀏覽器會設(shè)置每個(gè)來源5MB的限制,具體依瀏覽器而異
  • 對于sessionStorage,也因?yàn)g覽器而異,一般每個(gè)來源在2.5MB ~ 5MB 之間

瀏覽器支持情況
這兩者都都需要瀏覽器的API支持,瀏覽器的支持情況如下:

image.png

使用
通過window.localStoragewindow.sessionStorage這而兩個(gè)對象進(jìn)行操作

以操作localStorage為例:

  • 從存儲中獲取值
    window.localStorage.getItem('key')
function setStyles() {
  var currentColor = localStorage.getItem('bgcolor');
  var currentFont = localStorage.getItem('font');
  var currentImage = localStorage.getItem('image');

  document.getElementById('bgcolor').value = currentColor;
  document.getElementById('font').value = currentFont;
  document.getElementById('image').value = currentImage;

  htmlElem.style.backgroundColor = '#' + currentColor;
  pElem.style.fontFamily = currentFont;
  imgElem.setAttribute('src', currentImage);
}
  • 在存儲中設(shè)置值
    window.localStorage.setItem可以從存儲中獲取指定的數(shù)據(jù)項(xiàng)或者設(shè)置新的數(shù)據(jù)項(xiàng),該方法接受兩個(gè)參數(shù)——要?jiǎng)?chuàng)建/修改的數(shù)據(jù)項(xiàng)的鍵,和對應(yīng)的值。
function populateStorage() {
  localStorage.setItem('bgcolor', document.getElementById('bgcolor').value);
  localStorage.setItem('font', document.getElementById('font').value);
  localStorage.setItem('image', document.getElementById('image').value);
  setStyles();
}
  • 通過 StorageEvent 響應(yīng)存儲的變化
    無論何時(shí),storage對象發(fā)生變化時(shí)(即創(chuàng)建/更新/刪除,重復(fù)設(shè)置相同的項(xiàng)不會觸發(fā),storage.clear()方法至多觸發(fā)一次),都會觸發(fā)StorageEvent事件
    window.addEventListener('storage', function(){});
    示例:
window.addEventListener('storage', function(e) {  
  document.querySelector('.my-key').textContent = e.key;
  document.querySelector('.my-old').textContent = e.oldValue;
  document.querySelector('.my-new').textContent = e.newValue;
  document.querySelector('.my-url').textContent = e.url;
  document.querySelector('.my-storage').textContent = e.storageArea;
});

注意:在同一個(gè)頁面內(nèi)發(fā)生的改變不會起作用——在相同域名下的其他頁面(如一個(gè)新標(biāo)簽或 iframe)發(fā)生的改變才會起作用。在其他域名下的頁面不能訪問相同的 Storage 對象。

  • 刪除數(shù)據(jù)記錄
    window.localStorage.removeItem():接收一個(gè)參數(shù),要?jiǎng)h除的數(shù)據(jù)項(xiàng)key值
    window.localStorage.clear():不接收參數(shù),只是簡單的清空域名對應(yīng)的整個(gè)存儲數(shù)據(jù)

cookie

起源: 最初由網(wǎng)景公司引入,用于在客戶端存儲回話信息

工作方式:要求服務(wù)器對任意HTTP請求,在響應(yīng)頭中添加Set-Cookie 字段來設(shè)置cookie,在客戶端接收到這個(gè)cookie信息之后,將其存儲起來,在此之后,當(dāng)客戶端再給創(chuàng)建它的域名發(fā)送HTTP請求時(shí),都會在HTTP頭中添加cookie信息,服務(wù)器可以根據(jù)這個(gè)cookie信息來決定該用戶可以執(zhí)行哪些操作(例如:是否允許它進(jìn)行訪問)

cookie的組成:
cookie由瀏覽器保存在客戶端計(jì)算機(jī)中,由以下幾塊信息組成:

  • 名稱:cookie的名稱,這是唯一的,且字符不區(qū)分大小寫。注意:cookie的名稱必須是經(jīng)過URL編碼的
  • :存儲在cookie中的字符串值。注意:值必須經(jīng)過URL編碼
  • :cookie對于哪個(gè)域有效,所有向該域發(fā)送的請求中,都會包含這個(gè)cookie信息,如果沒有設(shè)置,則這個(gè)域會被認(rèn)作是設(shè)置cookie的那個(gè)域
  • 路徑:對于域下的路徑訪問,會包含cookie信息
  • 失效時(shí)間
  • 安全標(biāo)志

一個(gè)服務(wù)器發(fā)給客戶端的SetCookie信息,如下:

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; path=/; secure
Other-header: other-header-value

Set-cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT domain=.wrox.com; path=/; secure
這個(gè)Set-cookie的解釋如下:

  • cookie名稱: name
  • cookie的值:value (注意:值跟名稱是不同的東西)
  • 失效時(shí)間:Mon, 22-Jan-07 07:10:24 GMT;(這是GMT時(shí)間)
  • 域名: .wrox.com
  • 路徑: /
  • 安全標(biāo)志: secure(只有當(dāng)客戶端通過SSH連接時(shí),才可以傳輸該cookie)

cookie的特點(diǎn)

  • 創(chuàng)建方式:是由服務(wù)器來創(chuàng)建 cookie 信息的
  • 存放位置:客戶端接收到服務(wù)器的cookie信息之后,將其存放在客戶端的計(jì)算機(jī)中
  • cookie個(gè)數(shù)限制:cookie是綁定在域名下的,因此每個(gè)域的cookie個(gè)數(shù)是有限的,不同瀏覽器的限制不同,一般為50個(gè),chrome和safari沒有硬性限制。
  • cookie尺寸限制:對于每個(gè)域下的cookie的尺寸限制為4K字節(jié)注意:是一個(gè)域下的所有cookie的總尺寸之和要小于4K字節(jié),不是單個(gè)cookie的尺寸
  • 失效時(shí)間:默認(rèn)情況下,瀏覽器會話結(jié)束時(shí)即將所有的cookie刪除,但是,可以自己設(shè)置失效時(shí)間,當(dāng)未到達(dá)失效時(shí)間時(shí),cookie將一直保存在客戶端計(jì)算機(jī)中,除非自己手動刪除
  • cookie會被附加在每個(gè)http請求中,因此會增加流量
  • 安全標(biāo)志:當(dāng)指定后(通過Set-Cookie中添加 secure 關(guān)鍵字即可),cookie只有在使用SSL連接的時(shí)候才發(fā)送到服務(wù)器

注意事項(xiàng)

  • cookie個(gè)數(shù)和尺寸的限制,超過限制后,不同的瀏覽器有不同的處理方式,因此,一定不要超過限制
  • 域、路徑、失效時(shí)間和secure標(biāo)志都是服務(wù)器給瀏覽器的指示,以指定何時(shí)應(yīng)該發(fā)送cookie,這些參數(shù)不會作為發(fā)送給服務(wù)器cookie信息的一部分
  • cookie的名稱是經(jīng)過URL編碼的,注意:是名稱
  • Javascipt中處理cookie有些復(fù)雜,主要是接口不好用,即:document.cookie

cookie的缺陷

  • cookie會被附加在每個(gè)http請求中,因此會無形中增加流量
  • 由于http請求中的cookie是明文傳輸,因此有安全問題(除非使用https),不要使用cookie存放重要的數(shù)據(jù)
  • cookie的大小限制是4kb,對于復(fù)雜的存儲需求可能不夠用

cookie的使用

  • 獲取cookie:document.cookie,通過該方法可以獲取cookie
  • 刪除cookie:設(shè)置document.cookie并不會覆蓋cookie,除非設(shè)置的cookie的名稱已經(jīng)存在。那么就會對原cookie進(jìn)行覆蓋
    封裝的cookie代碼
let CookieUtil = {
    get: (name) => {
      let cookieName = encodeURIComponent(name) + "=",
          cookieStart = document.cookie.indexOf(cookieName),
          cookieValue = null;

      if (cookieStart > -1) {
        let 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) {
      let 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;
    },

    // 刪除cookie, 并沒有直接的刪除cookie的方法,這里通過重新設(shè)置cookie名稱,來對cookie進(jìn)行替換
    // 同時(shí) 將過期時(shí)間expires設(shè)置為過去的時(shí)間,
    unset: function(name, path, domain, secure) {
      this.set(name, '', new Date(0), path, domain, secure);
    }
  }

瀏覽器本地存儲中 cookie 和 localStorage 有什么區(qū)別? localStorage 如何存儲刪除數(shù)據(jù)。

sessionStorage、localStorage和cookie 這三者都是用于瀏覽器端存儲數(shù)據(jù),而且都是字符串類型的鍵值對

區(qū)別在于:

  • 數(shù)據(jù)傳輸方面:在每個(gè)http請求中都會附加cookie信息,cookie中的信息能夠被推送到服務(wù)器端;而sessionStorage和localStorage不會被推送到服務(wù)器端
  • 存儲大小不同:cookie最大支持4KB,而sessionStorage和localStorage一般在2.5~10MB
  • 生命周期:默認(rèn)情況下,cookie開始于瀏覽器啟動,結(jié)束于瀏覽器關(guān)閉,但是可以手動設(shè)置cookie的過期時(shí)間,同時(shí),到期后被刪除;而對于localStorage,沒有過期時(shí)間,原則上只要不手動刪除,其會一直被保存在本地上,sessionStorage的數(shù)據(jù)關(guān)閉瀏覽器時(shí)清除
  • 被創(chuàng)造的初衷不同:sessionStorage和localStorage都屬于WebStorage,創(chuàng)建他們的目的就是用于存儲客戶端數(shù)據(jù);
    而cookie最早在網(wǎng)景的瀏覽器中被支持,主要目的是為了辨別用戶身份而存儲在本地終端的數(shù)據(jù)。

參考:在HTML5的時(shí)代,重新認(rèn)識Cookie


參考:


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,978評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內(nèi)容