前端面試查漏補缺--(四) 前端本地儲存

shotCat發表於2019-02-22

前言

本系列最開始是為了自己面試準備的.後來發現整理越來越多,差不多有十二萬字元,最後決定還是分享出來給大家.

為了分享整理出來,花費了自己大量的時間,起碼是隻自己用的三倍時間.如果喜歡的話,歡迎收藏,關注我!謝謝!

文章連結

合集篇:

前端面試查漏補缺--Index篇(12萬字元合集) 包含目前已寫好的系列其他十幾篇文章.後續新增值文章不會再在每篇新增連結,強烈建議議點贊,關注合集篇!!!!,謝謝!~

後續更新計劃

後續還會繼續新增設計模式,前端工程化,專案流程,部署,閉環,vue常考知識點 等內容.如果覺得內容不錯的話歡迎收藏,關注我!謝謝!

求一份內推

目前本人也在準備跳槽,希望各位大佬和HR小姐姐可以內推一份靠譜的武漢 前端崗位!郵箱:bupabuku@foxmail.com.謝謝啦!~

cookie

作用

cookie是純文字,沒有可執行程式碼。儲存資料,當使用者訪問了某個網站(網頁)的時候,我們就可以通過cookie來向訪問者電腦上儲存資料,或者某些網站為了辨別使用者身份、進行session跟蹤而儲存在使用者本地終端上的資料(通常經過加密)

如何工作
當網頁要發http請求時,瀏覽器會先檢查是否有相應的cookie,有則自動新增在request header中的cookie欄位中。這些是瀏覽器自動幫我們做的,而且每一次http請求瀏覽器都會自動幫我們做。這個特點很重要,因為這關係到“什麼樣的資料適合儲存在cookie中”。

儲存在cookie中的資料,每次都會被瀏覽器自動放在http請求中,如果這些資料並不是每個請求都需要發給服務端的資料,瀏覽器這設定自動處理無疑增加了網路開銷;但如果這些資料是每個請求都需要發給服務端的資料(比如身份認證資訊),瀏覽器這設定自動處理就大大免去了重複新增操作。所以對於那種設定“每次請求都要攜帶的資訊(最典型的就是身份認證資訊)”就特別適合放在cookie中,其他型別的資料就不適合了。

特徵

  1. 不同的瀏覽器存放的cookie位置不一樣,也是不能通用的。
  2. cookie的儲存是以域名形式進行區分的,不同的域下儲存的cookie是獨立的。
  3. 我們可以設定cookie生效的域(當前設定cookie所在域的子域),也就是說,我們能夠操作的cookie是當前域以及當前域下的所有子域
  4. 一個域名下存放的cookie的個數是有限制的,不同的瀏覽器存放的個數不一樣,一般為20個。
  5. 每個cookie存放的內容大小也是有限制的,不同的瀏覽器存放大小不一樣,一般為4KB
  6. cookie也可以設定過期的時間,預設是會話結束的時候,當時間到期自動銷燬

Cookie主要用於以下三個方面:

  • 會話狀態管理(如使用者登入狀態、購物車、遊戲分數或其它需要記錄的資訊)
  • 個性化設定(如使用者自定義設定、主題等)
  • 瀏覽器行為跟蹤(如跟蹤分析使用者行為等)

設定

  • 客戶端設定:
document.cookie = '名字=值';
document.cookie = 'username=cfangxu; domain=baike.baidu.com'    //並且設定了生效域
//在設定這些屬性時,屬性之間由一個分號和一個空格隔開。

//當我們需要設定多個cookie時
document.cookie = "name=Jonh";
document.cookie = "age=12";
document.cookie = "class=111";
複製程式碼

注意: 客戶端可以設定cookie下列選項:expires(過期時間)、domain(伺服器域名)、path(域名下的哪些路徑可以接受Cookie)、secure(有條件:只有在https協議的網頁中,客戶端設定secure型別的 cookie 才能成功),但無法設定HttpOnly選項。

  • 伺服器端設定

不管你是請求一個資原始檔(如 html/js/css/圖片),還是傳送一個ajax請求,服務端都會返回response。而response header中有一項叫set-cookie,是服務端專門用來設定cookie的。

Set-Cookie  //訊息頭是一個字串,其格式如下(中括號中的部分是可選的):
Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
複製程式碼

注意:一個set-Cookie欄位只能設定一個cookie,當你要想設定多個 cookie,需要新增同樣多的set-Cookie欄位。  服務端可以設定cookie 的所有選項:expires、domain、path、secure、HttpOnly  通過 Set-Cookie 指定的這些可選項只會在瀏覽器端使用,而不會被髮送至伺服器端。

讀取

我們通過document.cookie來獲取當前網站下的cookie的時候,得到的字串形式的值,它包含了當前網站下所有的cookie(為避免跨域指令碼(xss)攻擊,這個方法只能獲取非 HttpOnly 型別的cookie)。它會把所有的cookie通過一個分號+空格的形式串聯起來,例如username=chenfangxu; job=coding

修改 cookie

要想修改一個cookie,只需要重新賦值就行,舊的值會被新的值覆蓋。 但要注意一點,在設定新cookie時,path/domain這幾個選項一定要舊cookie 保持一樣。否則不會修改舊值,而是新增了一個新的 cookie。

刪除 把要刪除的cookie的過期時間設定成已過去的時間,path/domain/這幾個選項一定要舊cookie 保持一樣。

注意

  • cookie雖然是個字串,但這個字串中逗號、分號、空格被當做了特殊符號。所以當cookie的 key 和 value 中含有這3個特殊字元時,需要對其進行額外編碼,一般會用escape進行編碼,讀取時用unescape進行解碼;當然也可以用encodeURIComponent/decodeURIComponent或者encodeURI/decodeURI三者的區別可以參考這篇文章)。

  • 什麼時候 cookie 會被覆蓋:name/domain/path 這3個欄位都相同的時候;

expires

expires選項用來設定“cookie 什麼時間內有效”。**expires其實是cookie失效日期**,expires必須是 GMT 格式的時間(可以通過 new Date().toGMTString()或者new Date().toUTCString() 來獲得 )。

expires=Thu, 25 Feb 2016 04:18:00 GMT表示cookie講在2016年2月25日4:18分之後失效,對於失效的cookie瀏覽器會清空。如果沒有設定該選項,則預設有效期為session,即會話cookie。這種cookie在瀏覽器關閉後就沒有了。

expires 是 http/1.0協議中的選項,在新的http/1.1協議中expires已經由 max-age 選項代替,兩者的作用都是限制cookie 的有效時間。expires的值是一個時間點(cookie失效時刻= expires),而max-age 的值是一個以為單位時間段(cookie失效時刻= 建立時刻+ max-age)。 另外,max-age 的預設值是 -1(即有效期為 session );若max-age有三種可能值:負數、0、正數。負數:有效期session0:刪除cookie;正數:有效期為建立時刻+ max-age

domain 和 path

domain是域名,path是路徑,兩者加起來就構成了 URL,domainpath一起來限制 cookie 能被哪些 URL 訪問。

一句話概括:某cookie的 domain為“baidu.com”, path為“/ ”,若請求的URL(URL 可以是js/html/img/css資源請求,但不包括 XHR 請求)的域名是“baidu.com”或其子域如“api.baidu.com”、“dev.api.baidu.com”,且 URL 的路徑是“/ ”或子路徑“/home”、“/home/login”,則瀏覽器會將此 cookie 新增到該請求的 cookie 頭部中。

所以domainpath2個選項共同決定了cookie何時被瀏覽器自動新增到請求頭部中傳送出去。如果沒有設定這兩個選項,則會使用預設值。domain的預設值為設定該cookie的網頁所在的域名,path預設值為設定該cookie的網頁所在的目錄。

secure

通常 cookie 資訊都是使用HTTP連線傳遞資料,這種傳遞方式很容易被檢視,所以 cookie 儲存的資訊容易被竊取。假如 cookie 中所傳遞的內容比較重要,那麼就要求使用加密的資料傳輸。

secure選項用來設定cookie只在確保安全的請求中才會傳送。當請求是HTTPS或者其他安全協議時,包含 secure 選項的 cookie 才能被髮送至伺服器。

document.cookie = "username=cfangxu; secure"

把cookie設定為secure,只保證 cookie 與伺服器之間的資料傳輸過程加密,而儲存在本地的 cookie檔案並不加密。就算設定了secure 屬性也並不代表他人不能看到你機器本地儲存的 cookie 資訊。 機密且敏感的資訊絕不應該在 cookie 中儲存或傳輸,因為 cookie 的整個機制原本都是不安全的

注意:如果想在客戶端即網頁中通過 js 去設定secure型別的 cookie,必須保證網頁是https協議的。在http協議的網頁中是無法設定secure型別cookie的。

httpOnly

這個選項用來設定cookie是否能通過 js 去訪問。預設情況下,cookie不會帶httpOnly選項(即為空),所以預設情況下,客戶端是可以通過js程式碼去訪問(包括讀取、修改、刪除等)這個cookie的。當cookie帶httpOnly選項時,客戶端則無法通過js程式碼去訪問(包括讀取、修改、刪除等)這個cookie。

在客戶端是不能通過js程式碼去設定一個httpOnly型別的cookie的,這種型別的cookie只能通過服務端來設定。

——httpOnly與安全

從上面介紹中,大家是否會有這樣的疑問:為什麼我們要限制客戶端去訪問cookie?其實這樣做是為了保障安全。

試想:如果任何 cookie 都能被客戶端通過document.cookie獲取會發生什麼可怕的事情。當我們的網頁遭受了 XSS 攻擊,有一段惡意的script指令碼插到了網頁中。這段script指令碼做的事情是:通過document.cookie讀取了使用者身份驗證相關的 cookie,並將這些 cookie 傳送到了攻擊者的伺服器。攻擊者輕而易舉就拿到了使用者身份驗證資訊,於是就可以搖搖大擺地冒充此使用者訪問你的伺服器了(因為攻擊者有合法的使用者身份驗證資訊,所以會通過你伺服器的驗證)。

第三方cookie

通常cookie的域和瀏覽器地址的域匹配,這被稱為第一方cookie。那麼第三方cookie就是cookie的域和位址列中的域不匹配,這種cookie通常被用在第三方廣告網站。為了跟蹤使用者的瀏覽記錄,並且根據收集的使用者的瀏覽習慣,給使用者推送相關的廣告。  關於第三方cookie和cookie的安全問題可以檢視這篇文章

session和cookie區別

  • session儲存在伺服器,cookie儲存在客戶端
  • session中儲存的時物件,cookie儲存的是字串
  • session不能區分路徑,同一個使用者訪問一個網站期間,所有的session在任何一個地方都可以訪問
  • cookie如果設定路徑,則在某些地方不能訪問
  • session需要藉助cookie才能正常工作,如果禁用cookie,session則失效
  • 客戶端會在傳送請求的時候,自動將本地存活的cookie封裝在資訊頭髮送給伺服器 複製程式碼

session和cookie應用場景

  • session上下文機制,針對每一個使用者,通過sessionid來區分不同客戶
  • session是以cookie或url重寫為基礎的,預設使用cookie實現,系統會創造一個名為jsessionid的輸出cookie
  • 重要狀態走session,不重要走cookie,登陸資訊用session,購物車用cookie

localStorage(本地儲存)

HTML5新方法,僅IE8及以上瀏覽器相容。

特點:

  • 生命週期:持久化的本地儲存,除非主動刪除資料,否則資料是永遠不會過期的。
  • 儲存的資訊在同一域中是共享的
  • 當本頁操作(新增、修改、刪除)了localStorage的時候,本頁面不會觸發storage事件,但是別的頁面會觸發storage事件。
  • 大小:據說是5M(跟瀏覽器廠商有關係)
  • 在非IE下的瀏覽中可以本地開啟。IE瀏覽器要在伺服器中開啟。
  • localStorage本質上是對字串的讀取,如果儲存內容多的話會消耗記憶體空間,會導致頁面變卡
  • localStorage受同源策略的限制

設定

localStorage.setItem('username','cfangxu');

獲取

localStorage.getItem('username')  也可以獲取鍵名  localStorage.key(0) #獲取第一個鍵名

刪除

localStorage.removeItem('username')  也可以一次性清除所有儲存  localStorage.clear()

storage事件

當storage發生改變的時候觸發。

注意: 當前頁面對storage的操作會觸發其他頁面的storage事件  事件的回撥函式中有一個引數event,是一個StorageEvent物件,提供了一些實用的屬性,如下表:

Property Type Description
key String The named key that was added, removed, or moddified
oldValue Any The previous value(now overwritten), or null if a new item was added
newValue Any The new value, or null if an item was added
url/uri String The page that called the method that triggered this change

補充:
js跨頁面觸發事件,利用storage監聽事件 觸發storage事件的條件:

  • 同一瀏覽器開啟了兩個同源頁面
  • 其中一個頁面修改了localStorage
  • 另一個網頁註冊了這個事件

sessionStorage

其實跟localStorage差不多,也是本地儲存,會話本地儲存

特點

  • 用於本地儲存一個會話(session)中的資料,這些資料只有在同一個會話中的頁面才能訪問並且當會話結束後資料也隨之銷燬。因此sessionStorage不是一種持久化的本地儲存,僅僅是會話級別的儲存。也就是說只要這個瀏覽器視窗沒有關閉,即使重新整理頁面或進入同源另一頁面,資料仍然存在。關閉視窗後,sessionStorage即被銷燬,或者在新視窗開啟同源的另一個頁面,sessionStorage也是沒有的。

cookie、localStorage、sessionStorage區別

  • 相同:在本地(瀏覽器端)儲存資料
  • 不同:
    • localStorage只要在相同的協議、相同的主機名、相同的埠下,就能讀取/修改到同一份localStorage資料。

    • sessionStorage比localStorage更嚴苛一點,除了協議、主機名、埠外,還要求在同一視窗(也就是瀏覽器的標籤頁)下。

    • localStorage是永久儲存,除非手動刪除。

    • sessionStorage當會話結束(當前頁面關閉的時候,自動銷燬)

    • cookie的資料會在每一次傳送http請求的時候,同時傳送給伺服器而localStorage、sessionStorage不會。

web SQL database和indexedDB

這些不常用的前端儲存我就不在這裡多述了(其實就是我不會=.=).想詳細瞭解的可以檢視這篇文章

感謝及參考

相關文章