浏览器存储
cookie和session的区别
-
cookie数据存放在浏览器上,session存放在服务器上
-
cookie一般在客户端有大小限制,一般为4K,session没有限制,但是考虑到服务器性能,一般不能存放太多数据
-
cookie可以设置过期时间,否则一直有效,session在超过一定的时间(通常30min)后就会失效,当关闭浏览器时,会自动调用session.invalidate()方法,清除掉session中的信息
-
cookie安全性较低,可以通过分析本地的cookie并进行cookie欺骗,所以一般不用于存放敏感信息(如用户密码),session存储在服务器上,不存在敏感信息泄露的问题,安全性较高
-
cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或二进制数据,session中能够存储任何类型的数据,包括但不限于string,integer,list,map等
cookie
cookie是客户端的解决方案,是一种网络服务器存储在计算机或移动设备上的纯文本文件,是服务器发送到浏览器上的一小块数据,是一个在服务器和客户端之间来回传送文本值的内置机制,服务器可以根据cookie追踪用户在不同页面的访问信息
cookie的用处:
- 会话管理:用户账号密码
- 个性化:用户偏好设置
- 追踪:记录和分析用户行为
cookie的特点:
-
大小限制在4k以内
-
不加密则不安全
-
会消耗网络的带宽
-
使用JS操作cookie比较复杂
session
session是一种服务端解决方案,是服务器为了保存用户状态而创建的一个特殊对象,客户端请求服务端,服务端会为请求开辟一块空间,session弥补了HTTP无状态特性
session的创建过程:
- 当浏览器第一次访问服务器时,服务器会创建一个session对象(该对象有唯一的ID,即SessionID),服务器会将SessionID以cookie的方式返回浏览器,当浏览器再次访问服务器时,会将SessionID发送过来,服务器依据SessionID就可以找到对应的session对象
session的缺点:
- A服务器存储了session,做了负载均衡后,加入一段时间内A的访问量激增,会转发到B进行访问,但是B服务器中没有存储A的session,会导致session的失效
cookie,localStorage,sessionStorage的区别
- cookie可设置失效时间,默认为关闭浏览器后失效,sessionStorage仅在当前网页会话下有效,关闭页面或浏览器后就会被清除,localStorage除非手动清除,否则永久有效
- cookie存储数据大小在4K以内,sessionStorage和localStorage可以保存5M的信息
- 在进行请求时,cookie每次都会携带在请求头中,浪费带宽,如果cookie保存过多数据会产生性能问题,sessionStorage和localStorage仅在浏览器中保存,不参与和服务器的通信
- 从安全性来说,cookie安全性较低,所以一般不用来保存敏感信息,其他两个似乎也不安全。
- cookie区分域,不区分端口,同ip下的不同端口cookie是共享的,sessionStorage和localStorage不可共享
- 应用场景:
- cookie可以用于识别用户登录
- sessionStorage可用来保存一些临时的数据,防止用户刷新页面之后丢失了一些参数
- localStorage可以用来传递在页面传递参数
浏览器缓存(HTTP缓存机制)
强制缓存
- 浏览器初次请求或者缓存过期,服务端返回资源和Cache-Control(max-age=12321214s)
- 再次请求的时候,会判断Cache-Control信息是否还生效(时间是否过期),决定从本地拿缓存还是继续向服务器请求
Cache-Control的值
- max-age:时间限制
- no-cache:不做本地缓存,交给服务端
- no-store:不做本地强制缓存,也不让服务端做缓存,一请求一返回
- private:只允许最终用户访问(电脑、手机等)
- public:允许中间的一些路由、代理等访问
协商缓存
- 服务端缓存策略
- 服务器判断客户端资源,是否和服务端资源一样,一致则返回304,否则返回200和最新的资源
- 资源标识: 在Response Header中,有Last-Modified(资源的最后修改时间)和Etag(资源的唯一标识)两种:
- 可以两者一起使用,必须两者都有效服务端才会返回304
- 会优先使用Etag,因为Last-Modified只能精确到秒级,如果资源被重复生成,而内容不变,则Etag更精确
- 对于更改文件而文件内容不变的情况,用Etag更精确
- 某些服务器不能精确地得到文件最后修改的时间
按资源标识Etag(根据资源内容计算而来)
按Last-Modified(最后修改时间)
综述
- 第一次进入页面,请求服务器,然后服务器进行应答,浏览器会根据responseHeader(cache-control、expires等)来判断是否是对资源进行缓存,代表这是强制缓存
- 客户端再次发起请求时,先查询浏览器是否有缓存,若没有则直接向服务器请求
- 若有缓存,根据Cache-Control判断缓存是否过期,若未过期,则直接读取缓存(强制缓存)
- 若缓存过期,判断是否有Etag和Last-Modified,若没有,则直接向服务器请求,服务器返回资源+
Etag/Last-Modified
- 若有,则向服务器请求并带上
If-No-Match(key: Etag)、If-Modified-Since(key: Last-Modified)
字段(协商缓存) - 服务器根据If-None-Match、If-Modified-Since判断资源是否改变(根据Etag/最后修改时间是否相同判断)
- 若资源发生改变,则返回200状态码+资源+新的
Etag/Last-Modified
- 若未发生改变,则读取缓存+304状态码
浏览器缓存行为和用户行为的关系
用户操作 | Expires/Cache-Control | Last-Modified/Etag |
---|---|---|
地址栏回车 | 有效 | 有效 |
页面链接跳转 | 有效 | 有效 |
新开窗口 | 有效 | 有效 |
前进、后退 | 有效 | 有效 |
F5刷新 | 无效 | 有效 |
Ctrl+F5刷新 | 无效 | 无效 |
缓存位置
Service Worker、Memory Cache、Disk Cache、Push Cache,各自有优先级,依次查找缓存都没有命中的时候才去请求网络
- 内存缓存(memory cache):内存缓存具有两个特点,分别是快速读取和时效性
- 快速读取:内存缓存会将编译解析后的文件,直接存入该进程的内存中,以方便下次运行使用时的快速读取。
- 时效性:关闭页面时,缓存的资源就会被进程释放
- 硬盘缓存(disk cache):硬盘缓存则是直接将缓存写入硬盘文件中,读取缓存需要对该缓存存放的硬盘文件进行I/O操作,然后重新解析该缓存内容,读取复杂,速度慢,持久化。
- Service Worker:间于浏览器和服务器的中间人角色,运行在浏览器背后的独立线程,基于h5的web worker,一般可以用来缓存文件。可以拦截当前网站的请求,进行判断,如果可以使用缓存就直接返回缓存,否则将请求转给服务器,传输协议必须为https
- 推送缓存(Push Cache):是HTTP/2的内容
- 所有资源都能够被缓存、推送(Edge和Safari支持相对比较差)
- 可以推送no-cache和no-store的资源
- 一旦连接关闭Push Cache就会被释放
- 多个页面可以使用同一个Http/2连接,也就可以使用同一个push cache(有的浏览器会对同域不同tab使用同一个Http连接)
- push cach中的缓存只能被使用一次
- 浏览器可拒绝接受已存在的资源推送
- 可以给其他域名推送资源
在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。
Etag生成原理
在HTTP1.1协议中并没有规范如何计算ETag,可以是能够唯一标识资源的任何东西,如一个或多个文件属性。计算Etag开销最大的一般是采用哈希算法获取资源的表述值,可以只计算资源的哈希值,也可以包含头信息和头信息的值(应该避免包含Expires、Cache-Control等),先要组装资源的表述,若组装比较耗时,可以采用GUID的方式
Etag有两种类型:强Etag和弱Etag,与Apache服务器计算Etag的方式有关
- 强Etag表现形式:“22FAA065-2664-4197-9C5E-C92EA03D0A16”
- 弱Etag表现形式:w/“22FAA065-2664-4197-9C5E-C92EA03D0A16”