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相同后就不下载文件了(返回请求响应体为空)

你可能感兴趣的:(Cookie、Session、LocalStorage及HTTP缓存控制)