導(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