关于Cookie、Session、LocalStorage、Cache-Control,在总结前先了解一个过程:当用户在一个浏览器注册账号再登录,客户端和服务器发生了什么?
一、发生了什么?
1、用户打开注册页面,提交信息(登录名、密码……)后,客户端获取用户输入的信息保存到hash表里,并发送post请求路由为/sign_up给服务器
2、服务器判断路由后进行接受数据(字符串)并将字符串转化为对象处理,保存到数据库(一个文件里),并告知用户注册成功了(后端设置返回响应,前端根据响应内容来呈现页面给用户)
3、用户打开登录页面,提交信息(登录名、密码……)发送post请求路由为/sign_in给服务器
4、服务器判断这次的提交信息(登录名、密码……)在不在数据库里。如果不在,那么告知用户去注册一个。如果在那么就将SessionID(随机数)通过cookie发给客户端。每一个SessionID对应了一个用户的信息,但返回的cookie是一个随机数,因为随机数可以提高保密度。
5、客户端再次访问服务器时,就会给带上这个cookie,发送get请求给服务器。服务器读取SessionID。
6、服务器通过SessionID找到对应用户的隐私信息,然后进行判断。如果确定是同一个用户,那么响应一个新的html文件(登录后的页面)给客户端
那么……
二、关于Cookie
Cookie是什么?举个例子:
小明(浏览器)第一次去公园(服务器)的时候,公园给了小明一张票(Cookie,包含了小明的信息)并告诉小明2天内(Cookie的有效时间)带着这个票可以免费的进出,次数不限。所以小明在这段时间内,每次去公园都得带上票。
1、Cookie的特点:
- 服务器通过 Set-Cookie 响应头设置 Cookie
- 浏览器得到 Cookie 之后,每次访问相同域名的网页时都要带上 Cookie
- 服务器读取 Cookie 就知道登录用户的信息(email)
- 大小在 4kb 以内
2、在A浏览器登录得到的Cookie,会在B浏览器带上A浏览器的Cookie吗?
NO
3、Cookie 存在哪里?
存在 C 盘的一个文件里
4、Cookie会被用户篡改吗?
可以,但 Session 来解决这个问题,防止用户篡改
5、Cookie 有效期吗?
默认有效期20分钟左右,不同浏览器策略不同。后端可以强制设置有效期,具体语法看 MDN:
HTTP cookiesdeveloper.mozilla.org6、Cookie 遵守同源策略吗?
也有,不过跟 AJAX 的同源策略稍微有些不同:
- 当请求 qq.com 下的资源时,浏览器会默认带上 qq.com 对应的 Cookie,不会带上 baidu.com 对应的 Cookie
- 当请求 v.qq.com 下的资源时,浏览器不仅会带上 v.qq.com 的Cookie,还会带上 qq.com 的 Cookie
既然如此,那为什么要设置Session?
因为用户可以修改Cookie,那么就可以用别人的身份发送请求获取响应……
二、关于Session
Session是什么?继续刚刚的例子:
由于其他人可以修改票的信息拿着这张票进公园,所以公园(服务器)把所有人的信息储存在一个本子里(内存),并给每一个人的信息设置对应的随机数字(SessionID)作为票(Cookie)给用户。那么小明拿到的票就不是自己的信息而是一串随机数。当进小明再次公园的时候,公园就会核对这串随机数与本子上记录随机数进行核对。如果准确就可以进去了。
所以Session就是:
- 将 SessionID(随机数,保密性强)通过 Cookie 发给客户端
- 客户端访问服务器时,服务器读取 SessionID
- 服务器有一块内存(哈希表)保存了所有 session
- 通过 SessionID 我们可以得到对应用户的隐私信息,如 id、email
- 这块内存(哈希表)就是服务器上的所有 session
sessions[hash.seesionId].name //从内存里找到对应的ID,所对应的用户名
三、关于LocalStorage&SessionStorage
1、LocalStorage:
- LocalStorage 跟 HTTP 无关
- HTTP 不会带上 LocalStorage 的值
- 只有相同域名的页面才能互相读取 LocalStorage(没有同源那么严格)
- 每个域名 LocalStorage 最大存储量为 5Mb 左右(每个浏览器不一样)
- 常用场景:记录有没有提示过用户(没有用的信息,不能记录密码)
- LocalStorage 永久有效,除非用户清理缓存
LocalStorage的三个API:
localStorage.setItem(key,value) // 创建一个hash
localStorage.getItem(key) //得到对应的value
localStorage.clear() //清空
应用场景(用户第一次登录网页会提示“网页即将改版”,第二次登录就不会提示了)
let already = localStorage.getItem('已经提示过了')
if(!already){
alert('网页即将改版了')
localStorage.setItem('已经提示过了',true)
}
2、SessionStorage(会话存储):
- SessionStorage 跟 HTTP 无关
- HTTP 不会带上 SessionStorage 的值
- 只有相同域名的页面才能互相读取 SessionStorage (没有同源那么严格)
- 每个域名 SessionStorage 最大存储量为 5Mb 左右(每个浏览器不一样)
- SessionStorage 在用户关闭页面(会话结束)后就失效。
四、Cache-Control(缓存控制)&Expires&ETag
1、Cache-Control是对HTTP进行缓存优化的
如果想给哪个请求设置缓存,就在服务器给相关请求返回的文件设置以下代码:
response.setHeader(‘Cache-Control’,‘max-age=30’)//对某个文件设置30秒内缓存
举了例子:
- 当Chrome浏览器第一次向服务器发送了一个路径为/main.js的请求
- 服务器响应一个xxx文本,浏览器下载了这个文本并保存在内存中
- 在30秒内Chrome浏览器输入同样的URL,内存返回了该文本
- 30秒之后Chrome浏览器第三发发送请求,服务器响应文本,浏览器下载并保存这个文本你在内存中
- ……
2、Cache-Control设置了时间,如何更新缓存?
首页不能设置Cache-Control,因为浏览器不允许,因为用户刷新后根本就不会向服务器发送任何请求。
一般其他会设置1-10年,如果中途发生改变可以更改文件请求的URL,只要URL变了就会发送新的请求。
3、Cache-Control与Expires的区别?
Cache-Control后面的时间是缓存多长时间
response.setHeader(‘Cache-Control’,‘max-age=30’)
Expires的后面几分几秒过期指的是本地时间,如果本地时间错乱了……
response.setHeader(‘Expires’,‘//GM的时间’)
4、Cache-Control与ETag 的区别?
每一个文件都会有一个对应的md5(摘要算法),如果文件有一丝丝的变动md5的值就会相差很大。啥是md5,点连接查看。
https://zh.wikipedia.org/zh-hans/MD5zh.wikipedia.org那么使用ETag就会响应给客户端一个md5,当客户端下一次请求时会提交一个md5给服务器,服务器判断进行判断是否要响应一个文件给客户端。如果不需要响应文件,那么返回一个304给客户端。而Cache-Control是直接不请求。
304 有请求,有响应,但是响应没有第四部分
缓存没有请求
五、几个问题
1、Cookie 和 Session 的区别?
Session是基于Cookie实现的,因为Session 必须将 SessionID(随机数)通过 Cookie 发给客户端。浏览器得到 Cookie 之后,每次访问相同域名的网页时都要带上 Cookie。
2、Cookie 和 LocalStorage 的区别?
客户端每次访问相同域名时会带上cookie,最大容量4k。而LocalStorage跟HTTP无关,所以不会带上LocalStorage的值,5Mb。
3、LocalStorage 和 SessionStorage 的区别?
LocalStorage 永久有效,除非用户清理缓存。SessionStorage在用户关闭页面(会话存储)后就失效了。
4、Cookie 如何设置过期时间?如何删除 Cookie?
Cookie设置过期时间:
- Expires指定了一个日期/时间, 在这个日期/时间之后 Cookie 过期
- max-age指定了一个秒数,经过此秒数后 Cookie 过期
- 如果不设置这个标头,则默认关闭浏览器后 Cookie 过期
Cookie 的删除有不同方式:
- 服务器端可以通过设置 Expires、max-age 两个标签将 Cookie 设置为过期状态
- JavaScript 可以通过
document.cookie
API 删除 Cookie
5、Cache-Control: max-age=1000 缓存 与 ETag 的「缓存」有什么区别?
使用ETag就会响应给客户端一个md5,当客户端下一次请求时会提交一个md5给服务器,服务器判断进行判断是否要响应第四部分内容给客户端。如果不需要响应第四部分内容,那么返回一个304给客户端。而Cache-Control是在一段时间直接不请求。