咱們來聊聊Cookie、Session和Storage的那些事

導語

咱們在作項目的時候,常常把Cookie和Session掛在嘴邊,可實際對於他們瞭解的也是不多,只是會使用,但這遠遠不夠,熟練的掌握他們的特性才能把項目作的更好。下面咱們就來認識一下他們吧!php

### 先來了解一下Cachehtml

Cache表示數據緩存,合理的設置cache,它能夠幫助咱們提升訪問速度,減小請求(在緩存有效期內直接讀取Cache文件),減小文件從服務器直接拉取文件(緩存過時後,請求服務器器檢查文件是否被更改,如沒有被更改則返回304而後讀取Cache);nginx

Cache的數據通常是服務器上不常常變更的數據,如圖片、某些數據js、html、php等;若是是常常變更的數據通常是不被緩存的,沒有意義;若是把一個常常變更的文件緩存起來的話,沒有多大意義。segmentfault

讀取Cache的過程瀏覽器

首先檢查文件設置的緩存是否過時:緩存

  • 若是過時了,則會從新發送請求到服務器,檢查該文件是否有被更新,若是沒有被更新,則服務器會返回304 Not Modified,表示服務器上該文件沒有被更新,用戶發起的對該文件請求則會直接從本地cache讀取;若是服務上文件被更新了,則服務器會返回新的文件,此時http返回碼爲200 ok,更新緩存。
  • 若是沒有過時,則會直接讀取本地cache文件,再也不發起http請求;

在瀏覽器的控制檯的Network,咱們能夠看到一些文件的Headers,咱們來講說其中的一些頭部設置的做用:安全

Responese Headers服務器

access-control-allow-origin:*
cache-control:max-age=691200
content-length:0
date:Sun, 22 Apr 2018 03:25:41 GMT
etag:"5ad8603c-214cb"
expires:Fri, 27 Apr 2018 13:33:04 GMT
server:marco/2.0
status:304
via:T.3.H, M.ctn-fj-foc-007
x-request-id:30e1ceac71122f15ed9144c272406682

Request Headerscookie

:authority:static.segmentfault.com
:method:GET
:path:/v-5ad86038/3rd/assets.js
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, sdch, br
accept-language:zh-CN,zh;q=0.8
cache-control:max-age=0
if-modified-since:Thu, 19 Apr 2018 09:24:12 GMT
if-none-match:W/"5ad8603c-214cb"
origin:https://segmentfault.com
referer:https://segmentfault.com/user/settings?tab=notify
user-agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.5006.400 QQBrowser/9.7.13080.400
  • expires

    expires是HTTP/1.0控制網頁緩存的字段,表示服務器返回該請求結果緩存的到期時間,即再次發起該請求時,若是客戶端的時間小於Expires的值時,直接使用緩存結果;expires=當前服務器date+緩存有效時間;時間格式爲GTM,是一個絕對值。網絡

  • cache-control

    用戶控制http的緩存,max-age表示客戶端能夠接收生存期不大於指定時間(以秒爲單位)的響應;max-age=0;表示每次請求該文件時,都須要請求服務器檢查文件在上一次被緩存時有無修改過;max-age=10;表示10s內再次對該文件發起請求則不須要向服務器發起請求讀取文件,直接讀取本地cache文件;

    在HTTP/1.1中,Cache-Control是最重要的規則,主要用於控制網頁緩存,主要取值爲:

    • public:全部內容都將被緩存(客戶端和代理服務器均可緩存)
    • private:全部內容只有客戶端能夠緩存,Cache-Control的默認取值
    • no-cache:客戶端緩存內容,可是是否使用緩存則須要通過協商緩存來驗證決定
    • no-store:全部內容都不會被緩存,即不使用強制緩存,也不使用協商緩存
    • max-age=xxx (xxx is numeric):緩存內容將在xxx秒後失效,是一個相對值
因爲**Cache-Control的優先級比expires**,那麼直接根據Cache-Control的值進行緩存,意思就是說在600秒內再次發起該請求,則會直接使用緩存結果,強制緩存生效。

***注:在沒法肯定客戶端的時間是否與服務端的時間同步的狀況下,Cache-Control相比於expires是更好的選擇,因此同時存在時,只有Cache-Control生效。***

以上只是簡單的瞭解一下Cache,更深刻的瞭解瀏覽器的緩存機制,能夠看看這篇文章-->完全理解瀏覽器的緩存機制,講得深刻,看完會對你有很大的幫助。

Cookie

Cookie是客戶端存儲數據的一個一種選項

當咱們向服務器發送任意的HTTP請求的時候,服務器會返回一個帶有Set-Cookie的HTTP響應頭返回給瀏覽器,其中包含一些會話信息。這種響應頭可能以下:

// Response Headers 響應頭

HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Sun, 22 Apr 2018 06:16:14 GMT
Content-Type: text/html
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: SID=t65ln3kllu7ujutldk4hcota05; path=/
Content-Encoding: gzip

這個響應頭設置SID爲名稱,t65ln3kllu7ujutldk4hcota05爲值的一個Cookie。

若是用戶不是第一次訪問,即:本地已經存在cookie,則在發送請求時會將cookie一併發給服務器,服務器收到請求以後會做出相應處理,返回對應的信息;這種請求頭可能以下:

// request Headers 請求頭

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-CN,zh;q=0.8
Connection:keep-alive
Cookie: SID=t65ln3kllu7ujutldk4hcota05

Cookie的設置

設置方式爲:

document.cookie="name=value;domain=域名;path=/;expires=過時時間;secure"

其中name和value是必須,其餘爲可選;name和value都須要通過URL編碼--encodeURIComponent()

如今介紹一下Cookie的構成:

  • name :一個惟一肯定Cookie的名稱,不區分大小寫,獲取Cookie是根據name來查找
  • value:存儲在Cookie中的字符串值
  • domain:Cookie對於哪一個域有效,好比domain="aa.qq.com",那麼qq.com就不能夠讀取該Cookie,若是沒有設置,會默認該請求來自當前域。
  • path:對於指定域中的哪一個路徑。好比path="/book/",那麼對於www.aa.qq.com/cc/的請求就不能發送Cookie
  • expires:Cookie過時時間,這個值是GMT格式的日期
  • secure:設置這個標誌後,Cookie只有在SSL連接的時候纔會發送給服務器,好比https://www.aa.qq.com能夠,而http://www.aa.qq.com就不行

Cookie的缺點

  • Cookie在每一個瀏覽器以及版本的數量都不一樣

    • IE6一下版本每一個域名最多20個
    • IE7以上的版本每一個域名最多50個
    • FireFox每一個域名最多50個
    • Opera每一個域名最多30個
    • Safari和Chrome沒有硬性規定,應該是有一個極限的
  • 大小受限,通常是在4k左右,最好別超過4k
  • 用戶能夠操做禁用cookie,使功能受限
  • 安全性較低
  • 有些狀態不可能保存在客戶端
  • 每次訪問都要傳送cookie給服務器,浪費帶寬。
  • cookie數據有路徑(path)的概念,能夠限制cookie只屬於某個路徑下。

瀏覽器提供設置Cookie方法比較簡陋,操做會比較麻煩,咱們能夠本身動手封裝一個

class CookieUtil{
    constructor(){

    }

    get(name){
        var cookies=document.cookie.split(";");
        var curCookie;
        for(var i=0;i<cookies.length;i++){
            curCookie=cookies[i].split("=");
            if(decodeURIComponent(curCookie[0])===name){
                return decodeURIComponent(curCookie[1])
            }

        }
        return null;
    }
    set(name,value,expires,domain,path,secure){
        if(!name&&!value){
            return
        }
        var cookieStr=encodeURIComponent(name)+"="+encodeURIComponent(value);
        if(expires && (expires instanceof Date)){
            cookieStr+=";expires="+expires.toGMTString();
        }

        if(path){
            cookieStr+=";path="+path
        }
        if(domain){
            cookieStr+=";domain="+domain
        }
        if(secure){
            cookieStr+=";secure"
        }
        document.cookie=cookieStr;
    }

    delete(name,domain,path,secure){
        this.set(name,"",new Date(0),domain,path,secure)
    }
}

Session

Session是保存在服務端的,經過相似與Hashtable的數據結構來保存,能支持任何類型的對象(session中可含有多個對象)

Session機制

當服務器收到請求須要建立session對象時,首先會檢查客戶端請求中是否包含sessionid。若是有sessionid,服務器將根據該id返回對應session對象。若是客戶端請求中沒有sessionid,服務器會建立新的session對象,並把sessionid在本次響應中返回給客戶端。一般使用cookie方式存儲sessionid到客戶端,在交互中瀏覽器按照規則將sessionid發送給服務器。若是用戶禁用cookie,則要使用URL重寫,能夠經過response.encodeURL(url)進行實現;API對encodeURL的約束爲:當瀏覽器支持Cookie時,url不作任何處理;當瀏覽器不支持Cookie的時候,將會重寫URL將SessionID拼接到訪問地址後。

Session的優勢

  • 大小沒有限制
  • session的安全性大於cookie,緣由以下:

    • sessionID存儲在cookie中,若要攻破session首先要攻破cookie
    • sessionID是要有人登陸,或者啓動session_start(php中的方法)纔會有,因此攻破cookie也不必定能獲得sessionID
    • 第二次啓動session_start後,前一次的sessionID就是失效了,session過時後,sessionID也隨之失效。
    • sessionID是加密的

Session的缺點

  • Session保存的東西越多,就越佔用服務器內存,對於用戶在線人數較多的網站,服務器的內存壓力會比較大。
  • 依賴於cookie(sessionID保存在cookie),若是禁用cookie,則要使用URL重寫,不安全
  • 建立Session變量有很大的隨意性,可隨時調用,不須要開發者作精確地處理,因此,過分使用session變量將會致使代碼不可讀並且很差維護。

Storage

WebStorage目的是克服由cookie所帶來的一些限制,當數據須要被嚴格控制在客戶端時,不須要持續的將數據發回服務器。

Webstorage的兩個主要目標:

  • 提供一種在cookie以外存儲會話數據的路徑。
  • 提供一種存儲大量能夠跨會話存在的數據的機制。

HTML5的WebStorage提供了兩種API:localStorage(本地存儲)和sessionStorage(會話存儲)。

  • 生命週期

    • localStorage:localStorage的生命週期是永久的,關閉頁面或瀏覽器以後localStorage中的數據也不會消失。localStorage除非主動刪除數據,不然數據永遠不會消失。
    • sessionStorage的生命週期是在僅在當前會話下有效。sessionStorage引入了一個「瀏覽器窗口」的概念,sessionStorage是在同源的窗口中始終存在的數據。只要這個瀏覽器窗口沒有關閉,即便刷新頁面或者進入同源另外一個頁面,數據依然存在。可是sessionStorage在關閉了瀏覽器窗口後就會被銷燬。同時獨立的打開同一個窗口同一個頁面,sessionStorage也是不同的。
  • 存儲大小:

    • localStorage和sessionStorage的存儲數據大小通常都是:5MB
  • 存儲位置:

    • localStorage和sessionStorage都保存在客戶端,不與服務器進行交互通訊。
  • 存儲內容類型:

    • localStorage和sessionStorage只能存儲字符串類型,對於複雜的對象可使用ECMAScript提供的JSON對象的stringify和parse來處理
  • 獲取方式:

    • localStorage:window.localStorage;;
    • sessionStorage:window.sessionStorage;。
  • 應用場景:

    • localStoragese:經常使用於長期登陸(+判斷用戶是否已登陸),適合長期保存在本地的數據。
    • sessionStorage:敏感帳號一次性登陸;

WebStorage的優勢:

  • 存儲空間更大:

    • cookie爲4KB,而WebStorage是5MB;
  • 節省網絡流量:

    • WebStorage不會傳送到服務器,存儲在本地的數據能夠直接獲取,也不會像cookie同樣美詞請求都會傳送到服務器,因此減小了客戶端和服務器端的交互,節省了網絡流量;
  • 對於那種只須要在用戶瀏覽一組頁面期間保存而關閉瀏覽器後就能夠丟棄的數據,sessionStorage會很是方便;
  • 快速顯示:

    • 有的數據存儲在WebStorage上,再加上瀏覽器自己的緩存。獲取數據時能夠從本地獲取會比從服務器端獲取快得多,因此速度更快;
  • 安全性:

    • WebStorage不會隨着HTTP Header發送到服務器端,因此安全性相對於cookie來講比較高一些,不會擔憂截獲,可是仍然存在僞造問題;
  • WebStorage提供了一些方法,數據操做比cookie方便;

    • setItem (key, value) —— 保存數據,以鍵值對的方式儲存信息。
    • getItem (key) —— 獲取數據,將鍵值傳入,便可獲取到對應的value值。
    • removeItem (key) —— 刪除單個數據,根據鍵值移除對應的信息。
    • clear () —— 刪除全部的數據
    • key (index) —— 獲取某個索引的key
相關文章
相關標籤/搜索