我們來聊聊Cookie瓢颅、Session和Storage的那些事

導(dǎo)語

我們在做項目的時候肛响,經(jīng)常把Cookie和Session掛在嘴邊,可實際對于他們了解的也是很少惜索,只是會使用,但這遠遠不夠剃浇,熟練的掌握他們的特性才能把項目做的更好巾兆。下面我們就來認識一下他們吧!

先來了解一下Cache

Cache表示數(shù)據(jù)緩存虎囚,合理的設(shè)置cache角塑,它可以幫助我們提高訪問速度,減少請求(在緩存有效期內(nèi)直接讀取Cache文件)淘讥,減少文件從服務(wù)器直接拉取文件(緩存過期后圃伶,請求服務(wù)器器檢查文件是否被更改,如沒有被更改則返回304然后讀取Cache);

Cache的數(shù)據(jù)一般是服務(wù)器上不經(jīng)常變動的數(shù)據(jù)窒朋,如圖片搀罢、某些數(shù)據(jù)js、html侥猩、php等;如果是經(jīng)常變動的數(shù)據(jù)一般是不被緩存的榔至,沒有意義;如果把一個經(jīng)常變動的文件緩存起來的話欺劳,沒有多大意義唧取。

讀取Cache的過程

首先檢查文件設(shè)置的緩存是否過期:

  • 如果過期了,則會重新發(fā)送請求到服務(wù)器划提,檢查該文件是否有被更新枫弟,如果沒有被更新,則服務(wù)器會返回304 Not Modified,表示服務(wù)器上該文件沒有被更新,用戶發(fā)起的對該文件請求則會直接從本地cache讀扰敉淡诗;如果服務(wù)上文件被更新了,則服務(wù)器會返回新的文件掸犬,此時http返回碼為200 ok,更新緩存袜漩。

  • 如果沒有過期,則會直接讀取本地cache文件湾碎,不再發(fā)起http請求;

在瀏覽器的控制臺的Network宙攻,我們可以看到一些文件的Headers,我們來說說其中的一些頭部設(shè)置的作用:

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 Headers

: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控制網(wǎng)頁緩存的字段介褥,表示服務(wù)器返回該請求結(jié)果緩存的到期時間座掘,即再次發(fā)起該請求時,如果客戶端的時間小于Expires的值時柔滔,直接使用緩存結(jié)果溢陪;expires=當(dāng)前服務(wù)器date+緩存有效時間;時間格式為GTM睛廊,是一個絕對值形真。

  • cache-control

    用戶控制http的緩存,max-age表示客戶端可以接收生存期不大于指定時間(以秒為單位)的響應(yīng)超全;max-age=0;表示每次請求該文件時咆霜,都需要請求服務(wù)器檢查文件在上一次被緩存時有無修改過;max-age=10;表示10s內(nèi)再次對該文件發(fā)起請求則不需要向服務(wù)器發(fā)起請求讀取文件嘶朱,直接讀取本地cache文件蛾坯;

    在HTTP/1.1中,Cache-Control是最重要的規(guī)則疏遏,主要用于控制網(wǎng)頁緩存脉课,主要取值為:

    • public:所有內(nèi)容都將被緩存(客戶端和代理服務(wù)器都可緩存)

    • private:所有內(nèi)容只有客戶端可以緩存救军,Cache-Control的默認取值

    • no-cache:客戶端緩存內(nèi)容,但是是否使用緩存則需要經(jīng)過協(xié)商緩存來驗證決定

    • no-store:所有內(nèi)容都不會被緩存倘零,即不使用強制緩存唱遭,也不使用協(xié)商緩存

    • max-age=xxx (xxx is numeric):緩存內(nèi)容將在xxx秒后失效粪狼,是一個相對值

    由于Cache-Control的優(yōu)先級比expires动羽,那么直接根據(jù)Cache-Control的值進行緩存,意思就是說在600秒內(nèi)再次發(fā)起該請求膳叨,則會直接使用緩存結(jié)果俐东,強制緩存生效跌穗。

    注:在無法確定客戶端的時間是否與服務(wù)端的時間同步的情況下,Cache-Control相比于expires是更好的選擇虏辫,所以同時存在時蚌吸,只有Cache-Control生效。

以上只是簡單的了解一下Cache砌庄,更深入的了解瀏覽器的緩存機制羹唠,可以看看這篇文章-->徹底理解瀏覽器的緩存機制,講得深入,看完會對你有很大的幫助娄昆。

Cookie

Cookie是客戶端存儲數(shù)據(jù)的一個一種選項佩微。

當(dāng)我們向服務(wù)器發(fā)送任意的HTTP請求的時候,服務(wù)器會返回一個帶有Set-Cookie的HTTP響應(yīng)頭返回給瀏覽器萌焰,其中包含一些會話信息哺眯。這種響應(yīng)頭可能如下:

// Response Headers 響應(yīng)頭

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

這個響應(yīng)頭設(shè)置SID為名稱,t65ln3kllu7ujutldk4hcota05為值的一個Cookie扒俯。

如果用戶不是第一次訪問奶卓,即:本地已經(jīng)存在cookie,則在發(fā)送請求時會將cookie一并發(fā)給服務(wù)器撼玄,服務(wù)器收到請求之后會作出相應(yīng)處理夺姑,返回對應(yīng)的信息;這種請求頭可能如下:

// request Headers 請求頭

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

Cookie的設(shè)置

設(shè)置方式為:

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

其中name和value是必須掌猛,其他為可選盏浙;name和value都需要經(jīng)過URL編碼--encodeURIComponent()

現(xiàn)在介紹一下Cookie的構(gòu)成:

  • name :一個唯一確定Cookie的名稱,不區(qū)分大小寫荔茬,獲取Cookie是根據(jù)name來查找

  • value:存儲在Cookie中的字符串值

  • domain:Cookie對于哪個域有效只盹,比如domain="aa.qq.com",那么qq.com就不可以讀取該Cookie兔院,如果沒有設(shè)置,會默認該請求來自當(dāng)前域站削。

  • path:對于指定域中的哪個路徑坊萝。比如path="/book/",那么對于www.aa.qq.com/cc/的請求就不能發(fā)送Cookie

  • expires:Cookie過期時間,這個值是GMT格式的日期

  • secure:設(shè)置這個標志后,Cookie只有在SSL鏈接的時候才會發(fā)送給服務(wù)器十偶,比如https://www.aa.qq.com可以菩鲜,而http://www.aa.qq.com就不行

Cookie的缺點

  • Cookie在每個瀏覽器以及版本的數(shù)量都不同

    • IE6一下版本每個域名最多20個
    • IE7以上的版本每個域名最多50個
    • FireFox每個域名最多50個
    • Opera每個域名最多30個
    • Safari和Chrome沒有硬性規(guī)定,應(yīng)該是有一個極限的
  • 大小受限惦积,一般是在4k左右接校,最好別超過4k

  • 用戶可以操作禁用cookie,使功能受限

  • 安全性較低

  • 有些狀態(tài)不可能保存在客戶端

  • 每次訪問都要傳送cookie給服務(wù)器狮崩,浪費帶寬蛛勉。

  • cookie數(shù)據(jù)有路徑(path)的概念,可以限制cookie只屬于某個路徑下睦柴。

瀏覽器提供設(shè)置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是保存在服務(wù)端的坦敌,通過類似與Hashtable的數(shù)據(jù)結(jié)構(gòu)來保存侣诵,能支持任何類型的對象(session中可含有多個對象)

Session機制

當(dāng)服務(wù)器收到請求需要創(chuàng)建session對象時,首先會檢查客戶端請求中是否包含sessionid狱窘。如果有sessionid杜顺,服務(wù)器將根據(jù)該id返回對應(yīng)session對象。如果客戶端請求中沒有sessionid蘸炸,服務(wù)器會創(chuàng)建新的session對象躬络,并把sessionid在本次響應(yīng)中返回給客戶端。通常使用cookie方式存儲sessionid到客戶端幻馁,在交互中瀏覽器按照規(guī)則將sessionid發(fā)送給服務(wù)器洗鸵。如果用戶禁用cookie,則要使用URL重寫仗嗦,可以通過response.encodeURL(url)進行實現(xiàn)膘滨;API對encodeURL的約束為:當(dāng)瀏覽器支持Cookie時,url不做任何處理稀拐;當(dāng)瀏覽器不支持Cookie的時候火邓,將會重寫URL將SessionID拼接到訪問地址后。

Session的優(yōu)點

  • 大小沒有限制

  • session的安全性大于cookie德撬,原因如下:

    • sessionID存儲在cookie中铲咨,若要攻破session首先要攻破cookie

    • sessionID是要有人登錄,或者啟動session_start(php中的方法)才會有蜓洪,所以攻破cookie也不一定能得到sessionID

    • 第二次啟動session_start后纤勒,前一次的sessionID就是失效了,session過期后隆檀,sessionID也隨之失效摇天。

    • sessionID是加密的

Session的缺點

  • Session保存的東西越多粹湃,就越占用服務(wù)器內(nèi)存,對于用戶在線人數(shù)較多的網(wǎng)站泉坐,服務(wù)器的內(nèi)存壓力會比較大为鳄。

  • 依賴于cookie(sessionID保存在cookie),如果禁用cookie腕让,則要使用URL重寫孤钦,不安全

  • 創(chuàng)建Session變量有很大的隨意性,可隨時調(diào)用纯丸,不需要開發(fā)者做精確地處理偏形,所以,過度使用session變量將會導(dǎo)致代碼不可讀而且不好維護液南。

Storage

WebStorage目的是克服由cookie所帶來的一些限制壳猜,當(dāng)數(shù)據(jù)需要被嚴格控制在客戶端時,不需要持續(xù)的將數(shù)據(jù)發(fā)回服務(wù)器滑凉。

Webstorage的兩個主要目標:

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

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

  • 生命周期

    • localStorage:localStorage的生命周期是永久的咒钟,關(guān)閉頁面或瀏覽器之后localStorage中的數(shù)據(jù)也不會消失。localStorage除非主動刪除數(shù)據(jù)若未,否則數(shù)據(jù)永遠不會消失朱嘴。

    • sessionStorage的生命周期是在僅在當(dāng)前會話下有效。sessionStorage引入了一個“瀏覽器窗口”的概念粗合,sessionStorage是在同源的窗口中始終存在的數(shù)據(jù)萍嬉。只要這個瀏覽器窗口沒有關(guān)閉,即使刷新頁面或者進入同源另一個頁面隙疚,數(shù)據(jù)依然存在壤追。但是sessionStorage在關(guān)閉了瀏覽器窗口后就會被銷毀。同時獨立的打開同一個窗口同一個頁面供屉,sessionStorage也是不一樣的行冰。

  • 存儲大小:

    • localStorage和sessionStorage的存儲數(shù)據(jù)大小一般都是:5MB
  • 存儲位置:

    • localStorage和sessionStorage都保存在客戶端伶丐,不與服務(wù)器進行交互通信悼做。
  • 存儲內(nèi)容類型:

    • localStorage和sessionStorage只能存儲字符串類型,對于復(fù)雜的對象可以使用ECMAScript提供的JSON對象的stringify和parse來處理
  • 獲取方式:

    • localStorage:window.localStorage;哗魂;
    • sessionStorage:window.sessionStorage;肛走。
  • 應(yīng)用場景:

    • localStoragese:常用于長期登錄(+判斷用戶是否已登錄),適合長期保存在本地的數(shù)據(jù)录别。
    • sessionStorage:敏感賬號一次性登錄羹与;

WebStorage的優(yōu)點:

  • 存儲空間更大:

    • cookie為4KB故硅,而WebStorage是5MB;
  • 節(jié)省網(wǎng)絡(luò)流量:

    • WebStorage不會傳送到服務(wù)器纵搁,存儲在本地的數(shù)據(jù)可以直接獲取,也不會像cookie一樣美詞請求都會傳送到服務(wù)器往踢,所以減少了客戶端和服務(wù)器端的交互腾誉,節(jié)省了網(wǎng)絡(luò)流量;
  • 對于那種只需要在用戶瀏覽一組頁面期間保存而關(guān)閉瀏覽器后就可以丟棄的數(shù)據(jù)峻呕,sessionStorage會非常方便利职;

  • 快速顯示:

    • 有的數(shù)據(jù)存儲在WebStorage上,再加上瀏覽器本身的緩存瘦癌。獲取數(shù)據(jù)時可以從本地獲取會比從服務(wù)器端獲取快得多猪贪,所以速度更快;
  • 安全性:

    • WebStorage不會隨著HTTP Header發(fā)送到服務(wù)器端讯私,所以安全性相對于cookie來說比較高一些热押,不會擔(dān)心截獲,但是仍然存在偽造問題斤寇;
  • WebStorage提供了一些方法桶癣,數(shù)據(jù)操作比cookie方便;

    • setItem (key, value) —— 保存數(shù)據(jù)娘锁,以鍵值對的方式儲存信息牙寞。
    • getItem (key) —— 獲取數(shù)據(jù),將鍵值傳入莫秆,即可獲取到對應(yīng)的value值间雀。
    • removeItem (key) —— 刪除單個數(shù)據(jù),根據(jù)鍵值移除對應(yīng)的信息镊屎。
    • clear () —— 刪除所有的數(shù)據(jù)
    • key (index) —— 獲取某個索引的key
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惹挟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子杯道,更是在濱河造成了極大的恐慌匪煌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件党巾,死亡現(xiàn)場離奇詭異萎庭,居然都是意外死亡,警方通過查閱死者的電腦和手機齿拂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門驳规,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人署海,你說我怎么就攤上這事吗购∫侥校” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵捻勉,是天一觀的道長镀梭。 經(jīng)常有香客問我,道長踱启,這世上最難降的妖魔是什么报账? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮埠偿,結(jié)果婚禮上透罢,老公的妹妹穿的比我還像新娘。我一直安慰自己冠蒋,他們只是感情好羽圃,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抖剿,像睡著了一般朽寞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牙躺,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天愁憔,我揣著相機與錄音,去河邊找鬼孽拷。 笑死吨掌,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脓恕。 我是一名探鬼主播膜宋,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼炼幔!你這毒婦竟也來了秋茫?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤乃秀,失蹤者是張志新(化名)和其女友劉穎肛著,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跺讯,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡枢贿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了刀脏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片局荚。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耀态,到底是詐尸還是另有隱情轮傍,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布首装,位于F島的核電站创夜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仙逻。R本人自食惡果不足惜挥下,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桨醋。 院中可真熱鬧,春花似錦现斋、人聲如沸喜最。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞬内。三九已至,卻和暖如春限书,著一層夾襖步出監(jiān)牢的瞬間虫蝶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工倦西, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留能真,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓扰柠,卻偏偏與公主長得像粉铐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子卤档,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

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