Cookie、Session、LocalStorage及HTTP缓存控制


title: Cookie、Session、LocalStorage及HTTP缓存控制
date: 2018-10-14 22:11:27
tags: [HTTP]
categories: HTTP


Cookie是什么?

通俗的说,Cookie 是浏览器访问服务器后,服务器传给浏览器的一段数据。此后每次浏览器访问该服务器,都必须带上这段数据。

特点:

  1. 服务器通过设置Set-Cookie响应头来设置 Cookie(给客户端一串字符串)
  2. 客户端每次访问相同域名的网页时,必须带上这段字符串
  3. 客户端要在一段时间内保存这个Cookie
  4. Cookie 默认在用户关闭页面后就失效,实际会在20分钟左右失效,根据浏览器而不同。但是后端可以强制设置有效期(相关可见MDN)。
  5. Cookie 的大小大概在4KB以内
  6. Cookie 实际上存在 C 盘的某个文件里

注意:

  1. Cookie 容易被用户篡改( 下面要讲的 Session 可以解决这个问题,防止用户篡改)
  2. Cookie 也有同源策略,不过跟 AJAX 的同源策略稍微有些不同。
    当请求 qq.com 下的资源时,浏览器会默认带上 qq.com 对应的 Cookie,不会带上 baidu.com 对应的 Cookie
    当请求 v.qq.com 下的资源时,浏览器不仅会带上 v.qq.com 的Cookie,还会带上 qq.com 的 Cookie

我们可以用Cookie实现:

  1. 识别用户身份
    比如用户登录网站后,服务器给浏览器Cookie,访问该域名的其他页面,服务器通过Cookie就知道你是谁了。
  2. 记录历史
    比如当用户浏览一个购物网战时,用户将商品添加到购物车,此时JS改写Cookie,将商品追加到其中并发送到服务器,当用户访问这个购物网站的其他页面时,带上这段Cookie,其他页面也知道购物车里有什么商品。

Cookie 的 HttpOnly 属性

如果包含服务端 Session 信息的 Cookie 不想被客户端 JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记。
Set-Cookie: id=allen; Expires=Wed, 21 Oct 2018 07:28:00 GMT; Secure; HttpOnly

如何删除cookie

通过设置cookie的有效期在当前时间之前来删除cookie

function deleteCookie(name){ 
    //方法一
    var date=new Date(); 
    date.setTime(date.getTime()-100);   // 当前毫秒数(时间)减去任意数字
    document.cookie = name + "=; expires=" + date.toGMTString(); 

    //方法二
    document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 
}

Session是什么?

特点:

  1. 将SessionId(随机数)通过Cookie发给客户端
  2. 客户端访问服务器时,服务器读取SessionId
  3. 服务器有一块内存(哈希表)保存了所有Session
  4. 通过SessionId我们可以得到对应用户的隐私信息,如id、email
  5. 这块内存(哈希表)就是服务器上的所有Session

使用:

为了不暴露用户的隐私信息,且不让用户直接通过浏览器修改Cookie。因此应这样使用Session:

let sessions = {}
let sessionId = Math.random() * 10000 // 设置sessionId 为一个随机数
sessions[sessionId] = {login_email:email} // 将email 存储在sessions这个对象中
response.setHeader('Set-Cookie', `sessionId = ${sessionId}`) // cookie中存储的是 sessionId 这个随机数

后台获取到cookie时,就可以获取到该随机数并在sessions这个对象中查找key为这个随机数的value,即可知道用户的邮箱是什么。


LocalStorage & SessionStorage

LocalStorage是HTML5提供的API,是window对象下的一个方法
本质是一个存在本地的hash

特点:

  1. LocalStorage 跟 HTTP 无关
  2. HTTP 不会带上 LocalStorage 的值
  3. 只有相同域名的页面才能互相读取 LocalStorage(没有同源那么严格)
  4. 每个域名 localStorage 最大存储量为 5Mb 左右(每个浏览器不一样)
  5. 常用场景:记录有没有提示过用户(没有用的信息,不能记录密码)
  6. LocalStorage 永久有效,除非用户清理缓存

常用api:

具体用法可见MDN

LocalStorage.setItem(name, value)
LocalStorage.GetItem(name)
LocalStorage.clear()

注意:

localStorage 只能存 string,所以如果想存Object,就需要用JSON来存,举个例子:
localStorage.setItem('jsonObj',JSON.stringify({name:'obj'}))
如果想要解析这个 JSON 将其转换成对象可以使用 JSON.parse()

常见的使用情景:

用户第一次进入页面时提示用户一些信息,第二次进入以后就不再提示。

let already = localStorage.getItem('isPrompt')
if(!already){
  alert('我们的页面改版啦')
  localStorage.setItem('isPrompt', true)
}else{
   // 已经提示了就什么也不做
}

SessionStorage(会话存储)

特点同LocalStorage,但是SessionStorage 在用户关闭页面(会话结束)后就失效。


HTTP缓存 Web性能优化

Cache-Control

如果网站需要加载的资源很多,导致每次刷新页面速度都非常都慢,那么该如何加快请求速度呢?这就有了缓存控制,Web性能优化的一部分。

response.setHeader('Cache-Control', 'max-age=30000')

设置max-age的时间,一般为一年,只要是相同的URL,客户端就不会向服务器发起请求,而是使用本地磁盘的缓存。

注意:

首页不应该设置缓存(Chrome甚至会直接禁用这个设置,你给首页设置Cache-Control也不会生效)。
因为如果你连首页都设置了缓存,用户即使刷新页面,也不会向服务器发送任何请求,那么如果你的代码更新了,用户在缓存期间将始终无法获取到最新的版本。

实际使用:

html页面不设置Cache-Control,其他资源Cache-Control设置一年以上,如果代码更新(比如js或css),该资源的请求的url的查询参数加上一个版本号,或者文件名后加随机数即可。
只要你的请求的url有一点点不一样,就不会使用缓存。


Expires

基本与Cache-Control相同,但Expires以用户的本地时间为基准。
这是个老技术了,现在一般优先使用Cache-Control

使用:

设置响应头,当过了设置的时间后缓存就过期了。
Expires:"Sun, 14 Oct 2018 23:01:17 GMT"

所以 Expires 与Cache-Control的区别就是:前者设置的是什么时候(看的是本地时间)过期,后者设置的是过了多久过期。


ETag & MD5

  1. Etag 是用来给文件一个版本号的
  2. MD5是一种信息摘要算法,验证文件是否修改
    你在网上下载一个很大的文件,下载过程中你怎么知道自己下载的对不对呢?MD5 为此而生

使用场景:

response.setHeader('ETag', MD5)
  1. 后端算出资源的MD5值,将其设置到响应头的Etag里
  2. 下一次请求时,这个资源的请求头就多了一个叫作If-None-Match的值:
  3. 后端设置:
    如果请求头的If-None-Match中的值和资源的MD5一样,说明资源是最新的,不需要下载,即可以返回304状态码( Not Modified),然后在此分支下就不用设置响应体了。
  4. 如果MD5的值不一样,说明你的资源需要更新,此时再返回最新的资源作为响应体。

Last-Modified

Last-Modified 是一个响应首部,其中包含源头服务器认定的资源做出修改的日期及时间。
精确度比 ETag 要低,这是一个备用机制。

使用过程:

  1. 第一次请求某一个URL时,有一个Last-Modified的属性标记在响应头里,此文件在服务期端最后被修改的时间
  2. 第二次请求此URL时,浏览器会向服务器传送If-Modified-Since请求头,询问该时间之后文件是否有被修改过
  3. 如果服务器端的资源没有变化,则返回304状态码;如果资源变化,像第一次一样重新发送资源

一些问题和总结

Cookie 和 Session 的区别

Session是基于Cookie实现的。
Cookie保存在客户端,每次都随请求发送给服务器
Session保存在服务器,将sessionID通过Cookie发送给客户端

Cookie 和 LocalStorage 的区别

客户端访问服务器会带上Cookie不带LocalStorage,LocalStorage跟HTTP无关
Cookie大概在4KB以内,LocalStorage在5M左右
Cookie默认在关闭页面后就失效,但后端可以设置 Cookie 的过期时间,而LocalStorage永久有效

LocalStorage 和 SessionStorage 的区别

LocalStorage永久有效
SessionStorage关闭页面(会话结束)后就失效

Cache-Control: max-age=1000 缓存 与 ETag 的「缓存」有什么区别?

Cache-Control 直接就不发送请求了
ETag 要发送请求,对比过md5相同后就不下载文件了(返回请求响应体为空)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361

推荐阅读更多精彩内容