前端存儲


前端存儲

轉載請注明出處:unclekeith: 前端存儲

前端存儲是每個前端開發工程師必備的技能。廢話不多說了,直接進入主題。

以下總結有關前端存儲方面的知識。主要是Cookie與WebStorage。當然,對於這兩種存儲方式的介紹,會與前端安全的問題一起討論

  • Cookie
    • Cookie定義
    • Cookie組成
    • Cookie大小
    • Cookie用途
    • Cookie缺點
  • Web Storage
    • Storage原型對象
    • sessionStorage對象
    • localStorage對象
    • Storage事件
  • IndexedDB
Cookie定義:

Cookie,中文名稱為'小型文本文件'或'小甜餅',指某些網站為了辨識用戶身份而存儲在用戶本地終端上的數據(通常name和value經過編碼)。

Cookie組成:

Cookie主要由以下幾個字段組成:

Cookie: [name][value][domain][path][expires][httpOnly][secure]

通常通過JS設置Cookie為以下形式。當然,最好的方式是通過一個函數來設置。

document.cookie = 'name=kk; domain=localhost; path=/; expires= Mon Nov 06 2017 01:32:07 GMT+0800 (CST)'

name, value: 是Cookie的名稱和值。Cookie的name和value必須經過url編碼。在JS中可以通過window.encodeURIComponent方法來對name和value進行編碼。同時,在寫cookie的時候要注意,cookie的名稱是不區分大小寫的。所以myCookie和MyCookie被認為是同一個cookie。但是在實際開發過程中,最好區分大小寫。

domain: Cookie對於哪個域是有效的。所以向該域發出的請求都會包含Cookie信息。設置Cookie時,如果不指定Cookie的值,默認就是本域名。如我在本地通過Node.js起服務器時,Cookie的domain為domain=localhost

子域可以獲取當前域(父域)的cookie,但是當前域(父域)不能獲取子域的cookie。比如說,當前域為a.com,在a.com設置了cookie。那么其子域b.a.com可以獲取a.com的cookie。但是如果在b.a.com設置的cookie,在a.com域名下不能獲取到b.a.com下的cookie。

path: 對於指定域中的那個路徑,應該向服務器發送cookie。默認情況下,如果不設置Cookie的path時,默認路徑為/。比如說,在a.com/profile路徑下設置的cookie,那么在訪問此路徑的時候才會發送cookie,在訪問a.com時不會發送cookie。

如果需要跨路徑獲取Cookie值,可以使用隱藏的iframe實現,但是必須是同源的。

expires:表示Cookie何時被刪除的時間戳。這個時間戳是GMT格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT)。如果設置成以前的時間,則Cookie會被立即刪除。如果設置的是將來的某個時間,那么即使關閉瀏覽器,cookie仍然保持在用戶的電腦上。expires字段的設置與否,會把Cookie分為兩種:本地(持久化)Cookie和內存(非持久化)Cookie。在介紹分類的時候再細說。

httpOnly: 顧名思義,httpOnly是指在HTTP層面上傳輸的Cookie。當服務端對Cookie消息設置了httpOnly標志之后,客戶端腳本就無法通過document.cookie的方式讀寫cookie。能夠讀取意味着可以獲取Cookie,能夠寫入Cookie意味着可以篡改Cookie。因此,對重要的Cookie消息設置httpOnly能夠有效防御XSS攻擊獲取Cookie。

secure: secure表明設置了secure字段的Cookie只能在HTTPS上進行安全數據傳輸。如果請求是HTTP的,就不會帶上這個Cookie。這里要留心一點的是,服務端設置cookie下的secure字段,它並不是以名稱-值對的形式的。而是單單一個secure單詞。例如,Cookie信息只能發送給https://keith.com,而http://keith.com的請求則不能發送Cookie。

如以下響應頭,其他字段是名稱-值對的形式,而secure是一個單詞。
HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: name=keith; domain=localhost; path=/; exipres=Mon, 08-June-18 07:10:24 GMT; secure

但是,有一個很特別的是設置了secure字段的Cookie可以被讀寫。因此,一般情況下,如果只允許HTTPS獲取數據,服務端可以一起配置secure + httpOnly字段,這樣就能夠保證HTTPS傳輸,並且避免了Cookie被讀寫的風險。

Cookie大小:

大多數瀏覽器Cookie默認大小為4kb。超過的部分會被截斷掉。

Cookie分類:

根據Cookie中的expires字段,可以將Cookie分為本地(持久化)Cookie和內存(非持久化)Cookie。

當expires沒有設置時,實際上就相當於一個內存Cookie。瀏覽器關閉之后就消失了。同時,在當前瀏覽器下,打開多個頁面仍然可以訪問到Cookie消息。也就是說,如果瀏覽器不關掉的情況下都會發送Cookie。

當expires設置一個未來的時間,那么就是一個本地Cookie。此時會將Cookie存入到操作系統本地,待過期時間到了才會消失。

因此根據expires字段,可以利用Cookie做用戶登錄認證、購物車信息存儲等功能。

Cookie用途:

當登錄一個網站的時候。

  1. 客戶端會將登錄的賬號和密碼發送到服務器。
  2. 服務器對賬號和密碼進行加密算法之后生成session文件,然后會在響應時將set-cookie帶在響應頭。
  3. 客戶端接着會將cookie保存在內存中。
  4. 客戶端下次請求的時候,會將cookie作為請求頭發往服務器。
  5. 服務器將對客戶端傳過來的cookie與session文件進行校驗,如果校驗通過,則可以直接登錄。

在購物場景中。

  1. 客戶端會將用戶已經選購的商品1發往服務器。
  2. 服務器會生成一份session文件,在響應時帶上set-cookie發往客戶端。
  3. 客戶端會保存服務端傳來的cookie.
  4. 用戶再次選擇商品2,進行以上同樣的操作。
  5. 此時用戶需要結賬,客戶端會將cookie發往服務器
  6. 進入結賬頁面時就會出現兩個商品。

Cookie缺點

1.Cookie的大小限制在4kb左右。對於復雜的存儲來說是不夠的

2.Cookie會被附加在每個HTTP請求中,所以會增加HTTP請求大小

3.由於Cookie都是在HTTP請求中明文傳遞的,會有安全性問題(除非使用HTTPS)

Web Storage

Storage原型對象

sessionStorage和localStorage對象都是繼承自Storage原型對象的。在Storage對象中存在以下方法

clear(): 清除所有storage
setItem(name, value): 設置storage, 也可以通過點語法或者方括號設置
getItem(name): 獲取name對應的value值, 也可以通過點語法或者方括號獲取
removeItem(name): 刪除單個storage。 也可以通過delete操作符刪除
key(index): 獲取index位置處的name
sessionStorage

sessionStorage存儲大小為5MB(大多數瀏覽器)。它屬於一種非持久化數據,在瀏覽器關掉時數據就消失了。同時,在瀏覽器未關閉,而重新開一個頁面(切換了路徑),也是無法訪問到sessionStorage的。因此在多頁面應用時有限制。可以使用localStorage來代替。

由於sessionStorage是對象,所以可以通過for-in語句或者結合length屬性來遍歷每個storage值,對於localStorage對象來說也是適用的。

// 方法一
for (let key in window.sessionStorage) {
    let value = window.sessionStorage[key]
    console.log(`${key}=${value}`)
}
// 方法二
for (let i = 0; i < window.sessionStorage.length; i++) {
    let key = window.sessionStorage.key(i)
    let value = window.sessionStorage[key]
    console.log(`${key}=${value}`)
}
localStorage

localStorage的存儲大小也為5MB(大多數瀏覽器)。localStorage會存儲在本地操作系統的文件中。在數據時效性上,localStorage並不會想cookie那樣可以設置數據的過期時間。也就是說,只要用戶不主動刪除localStorage,localStorage存儲的數據將會永久存在。

注意,localStorage無法跨瀏覽器存在。

這樣介紹一個看,localStorage即比Cookie擁有更大的數據存儲空間,而且數據也是持久化的,不會隨着網頁的關閉而消失,好像可以代替Cookie來做用戶身份驗證。

其實是不能的。我們知道,通常可以通過XSS漏洞來獲取到Cookie,然后用這個Cookie進行身份驗證登錄。但是為了防止通過XSS獲取到Cookie數據,服務器可以配置httpOnly來保護Cookie,禁止瀏覽器通過腳本document.cookie獲取到Cookie。而localStorage存儲沒有對XSS攻擊有任何的防御機制,一旦出現XSS漏洞,那么存儲在localStorage里的數據(如重要的用戶名、密碼)就極容易被獲取到。因此重要的信息不要存儲在storage對象中。

Storage事件

在改變sessionStorage對象或者localStorage對象之后,就會觸發Storage事件。也就是說,當刪除、修改、設置storage時,都會調用Storage事件。Storage事件的事件對象存在以下屬性。

domain: 發生變化的存儲的域名

key: 設置或刪除的鍵名

newValue: 如果是設置值,則對應一個新值;如果是刪除值,則是null

oldValue: 鍵值被修改前的值

document.addEventListener('storage', (e) => {
    console.log(e.domain)
    console.log(e.key)
    console.log(e.newValue)
    console.log(e.oldValue)
}, false)

IndexDB

這個目前我暫時還沒有用過....先占位,用過之后再回來填坑


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM