本次主要介绍一些 Session 、 LocalStroage 、 Cache-Control 相关知识并与上篇博客 Cookie 做一些对比说明。
一、Session
1、什么是 Session
说到 Session 一定要介绍一下 Cookie ,Cookie 是如何生成的:
- 服务器通过
HTTP相应头的Set-Cookie给客户端一段字符串, - 客户端每次访问相同域名的网页时都会自动带上这段
Cookie值 - 并且,这段
Cookie值会在客户端保存一定的时间 Cookie的大小一般为 4KBCookie的默认失效时间为用户关闭浏览器就失效了,但是服务器端可以Cookie的失效时间
Cookie 的本质其实就是 HTTP 请求的响应头的一部分。
介绍下 Session :Session 的出现出于对 Cookie 信息的安全性处理,如果 Cookie 值带上的用户的邮箱、账号、余额等隐私信息,那么在 Web 端是很容易被盗用或者篡改,此时 Session 出现, Session 是服务器端存在内存中的一段 hash 值,并且是通过随机数随机生成的,这个随机数对应的是某一个用户的用户信息,那么每次在客户端发起请求带来的 Session 值,就可以在服务端根据此值去找到对应的用户信息数据。具体的流程如下:
- 将
SessionId(随机数)通过Cookie发送给客户端 - 客户端访问服务器时,会带上
Cookie值,也就是服务端生成的SessionId(随机数),服务器读取SessionId - 服务器中的一块内存( hash 表 )保存了所有的
session - 通过
SessionId可以得到对应用户的隐私信息,如 id 、email - 这块内存表( hash 表 )就是服务器上的所有
Session
当然,如果服务器停止或者重启的话,这块内存表也会被清空。显然,Cookie 是不占用内存的,而 Session 是占用内存的。
二、LocalStorage
LocalStorage 是 Html5 提供的 API 。在浏览器控制台输入 localstorage 会打印出 LocalStorage 提供的所有 API 。如图所示:
以上 API 中 ,setItem()、getItem()、removeItem() 比较常用。 LocalStorage 的实质是一个 hash 表。使用方法如下:
12345678910 | // 存值localStorage.setItem('a',1);localStorage.setItem('b',2); localStorage.setItem('JsonString',JSON.stringify({"a":1,"b":2}));//取值let a = localStorage.getItem('a');let JsonObject = JSON.parse(localStorage.getItem('JsonString'));//删除值localStorage.removeItem('JsonString');localStorage.clear(); //删除所有 |
需要说明的是,localStorage 会将所有的值转换成字符串存入进入,比如一个 object 转换成字符串就变成了 [Object Object],所以对于复杂类型,在存入时最好使用 JSON.stringify() 先转换成 JSON 字符串再存入 localStroage 。
LocalStorage 的特点:
Localstorage与HTTP无关HTTP不会带上LocalStorage的值- 只有域名相同的页面才能相互读取
LocalStorage(没有同源那么严格) - 每个域名
LocalStorage最大存储量为 5M ,不同浏览器会有不同 - 常用场景:记录有没有提示过用户(没有用的信息,不能记录密码)
LocalStorage永久有效,除非用户清理
通常我们也会经常看到 SessionStorage ,二者的用法一致,唯一的区别是 SessionStorage 在用户关闭浏览器的时候自动清空,而 LocalStorage 则需要用户手动清理或者通过 JS 的 removeItem() 才能删除。
至此,面试经常会问到的关于 Cookie 、 Session 、 LocalStorage 大专栏 Session、LocalStorage、Cache-Control、 SessionStorage 的面试问题总结:
Cookie和Session是什么关系(参考标题一且Session是基于Cookie实现的)Cookie和LocalStorage有什么区别LocalStorage和SessionStorage有什么区别
三、Cache-Control
Cache-Control 也是可以在请求的响应头中进行设置,代码如下:
1 | res.setHeader('Cache-Control','max-age=30'); // 意思是 30s 内重复请求读取本地缓存 |
这样做能够加快页面打开速度,算是前端性能优化的一种。对于 Chrome 浏览器,是不允许对首页进行缓存设置的。
如何更新缓存?通常情况下,通过 setHeader 可以设置很长的失效期,但是在请求 css 或者 js 时只要路径有变化,都会重新请求,可以在引入 css 和 js 的地方加一个时间戳(不建议) 或者一个版本号(./css/base.css?v=1),通过改变查询参数就可以是客户端代码更新。
四、Expires
Expires 实现的功能和 Cache-Control 一样,但是 Cache-Control 是新的相应头,如果设置了 Cache-Control 那么就会忽略 Expires 的设置。代码如下:
1 | res.setHeader('Expires','Fri, 29 Jun 2018 06:41:15 GMT'); |
与 Cache-Control的不同在于 Cache-Control 是设置过多少秒后过期,而 Expires 是设置什么时候过期。
五、ETag
在介绍 ETag 之前需要先介绍下 MD5 。MD5 是典型应用是对一段信息(Message)产生信息摘要(Message-Digest),以防止被篡改。简单的说,比如现在有一个文本 1.txt ,文本内容为 123455 ,1.txt 的 md5 值为一段数字+字母的字符串,现复制 1.txt 到 2.txt ,那么 2.txt 的 md5 值与 1.txt 的 md5 值相同。如果修改其中一个文件内容,则修改的文件的 md5 值则会发生变化。简要的说,md5 能够用来校验文件是否相同。
1、使用 md5
在终端输入:npm install md5-node,然后在 server.js 中引入 const md5 = require('md5-node')
2、md5 与 ETag
12345678910111213141516 | // server.js... if(path === '/css/base.css'){ let str = fs.readFileSync('./css/base.css','utf-8'); res.setHeader('Content-Type','text/css;charset=utf-8'); let fileMd5 = md5(str); // 针对 base.css 文件生成 md5 值 if(req.headers['if-none-match'] === fileMd5){ // 根据请求头判断是否有 md5 的值 res.statusCode = 304; // 如果有的话,返回状态码 304 表示代码未修改 }else{ // 否则,重新设置 eTag 的值 res.setHeader('ETag',fileMd5); // 通过 ETag 将 md5 值传递到客户端,此时客户端收到响应会在 res.statusCode = 200; res.write(str); } res.end(); }... |
ETag 和 Cache-Control 的区别:ETag 会发送请求,但是响应体是空; Cache-Control 则不会发送请求,直接读取本地文件。