计算机网络(http缓存)| 强缓存、协商缓存、本地存储的方式🎨🎨

524 阅读11分钟

http缓存机制

强缓存:

cache-control:

max-age:表示缓存有效时间

no-cache:表示不设置强缓存,可以走协商缓存 

no-store:表示不设置缓存 

public:表示所有用户都可以缓存资源,服务器和客户端 

private:表示只有浏览器端可以缓存资源 

expires:是一个时间字符串,代表资源失效时间

协商缓存:

etag/if-none-match 返回的是一个检验码,第一次请求返回资源时,服务器返回的头部中会加上etag,再次资源时,请求头中会携带if-none-match,其值就是响应头中返回的ETag的值;服务器判断是否命中缓存,命中,返回304,不返回资源,但是还是会返回etag

last-modified/last-modified-since 第一次请求返回资源时,服务器返回的头部中会加上last-modified,代表上一次修改时间,再次请求资源时,请求头中会携带last-modified-since,值是上一次返回的last-modified的值,服务器判断是否命中缓存,命中,返回304,不返回资源,也不返回last-modified

浏览器缓存分类

什么是http缓存

http缓存指的是:当客户端向服务器端请求资源的时候,会先到达浏览器缓存,如果浏览器缓存中存在这个资源的“副本”,就可以直接从浏览器缓存中读取,不需要在向服务器端获取这个资源。

常见的http缓存只能缓存get请求响应的资源,对其他的类型的响应无能为力,所以http缓存讨论的都是get请求响应的资源。

http缓存分类

强缓存

当浏览器去请求某个文件的时候,服务器在response header里面对文件做了缓存配置, response header 的cache-control,常见的设置是max-age public private no-cache no-store等

image.png

cache-control: max-age=xxxx,public

public的意思是客户端和代理服务器都可以缓存该资源

客户端在xxx秒的有效期内,如果发起了请求就去直接读缓存,返回状态200,如果用户做了刷新操作,就去请求服务器。

cache-control: max-age=xxxx,private

private的意思是只有客户端可以进行缓存

客户端在xxx秒的有效期内,如果发起了请求就去直接读缓存,返回状态200,如果用户做了刷新操作,就去请求服务器。

cache-control: max-age=xxxx,immutable(强缓存

客户端在xxx秒的有效期内,如果发起请求就直接去读缓存,返回状态200,如果用户做了刷新操作也不会去请求服务器

cache-control: no-cache(不设置强缓存,不是字面意思的没有缓存)

跳过设置强缓存,但是不妨碍设置协商缓存

如果设置了强缓存,一般强缓存失效,才会去走协商缓存

但是设置了no-cache,就没有强缓存了,每次都会去请求服务器

cache-control: no-store

不缓存,没有强缓存或者协商缓存的说法

跟强制缓存相关的header头属性

image.png

协商缓存

上面说到的强缓存就是给资源设置一个过期时间,每次请求都去看过期了没有,如果过期了就去发送请求到服务器,如果没有过期就读取内存的数据。

这时候在去请求服务器的过程就可以设置协商缓存 response header里面的设置 这就是说,每次请求返回的response header的etag和last-modified,在下一次请求request header的时候都会带上,服务器把带过来的标识进行对比,如果没变就还是返回旧的,如果变了,就返回新的值。

对于客户端来说每次请求都要进行协商缓存了

发请求--->看资源是否过期--->过期--->请求服务器--->服务器对比是否真的过期--->没过期--->返回304 状态码--->客户端用缓存的资源

如果真的过期了,走下面这条路

发请求--->看资源是否过期--->过期--->请求服务器--->服务器对比是否真的过期--->过期--->返回200状态码--->客户端就向第一次请求资源一样,记录cache-control中的max-age、etag、last-modified的值

etag: '5c20abbd-e2e8' //可以理解成每个文件的id,唯一标识(实体标签)
last-modified: Mon, 24 Dec 2018 09:49:49 GMT // 上一次修改时间,精确到秒

思考💡: 为什么有etag?

主要解决last-modified的不足

1.一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新get;

2.某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),if-modified-since能检查到的粒度是秒级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);

3.某些服务器不能精确的得到文件的最后修改时间。

跟协商缓存相关的header头属性有(ETag/If-Not-Match 、 Last-Modified/If-Modified-Since)请求头和 响应头需要成对出现

image.png

2种缓存的对比

image.png

为什么需要http缓存

1.减少了冗余数据的传输

2.缓解了服务器的压力,大大提高了网站的性能

3.加快了客户端加载网页的速度

【扩展】

http1.0时代:

强缓存:pragma、Expire

协商缓存:Last-Modified、if-Modified-Since

http1.1时代:

强缓存:Cache-Control

协商缓存:ETag、if-Not-Match

小结

1.强缓存,服务器通知浏览器设置一个过期时间,在缓存时间内请求资源,直接读取缓存,时间过期,走协商缓存

2.协商缓存,将协商缓存的关键字段ETag/Last-Modified通过请求发给服务器端,由服务器检验,返回304状态码直接读取缓存,返回200服务器返回新的资源

3.浏览器首次请求和再次发送http请求的流程图

image.png

image.png

cookie原理

什么是cookie?

cookie是一段文本信息,是以字符串的形式存在的。

cookie是服务器端给用户颁发的一个状态值,存储在客户端或者浏览器中,只要在cookie的有效期内,再次向服务器端发送请求时,浏览器会先检查本地的cookie,如果存在,会自动将cookie加在请求头部一起发给服务器端,服务器端通过cookie识别用户的身份,并且将存储在服务器端的资源返回给用户。

cookie机制:

如果没有在浏览器端设置cookie的过期时间,cookie保存在内存中,生命周期随着浏览器的关闭而结束,这种cookie简称回话cookie。如果设置了过期时间,cookie保存在硬盘中,关闭浏览器以后cookie还会存在,到过期时间才会消失。

cookie的实现思路

(1)用户第一次访问服务器端,服务器会通过Set-Cookie返回客户端,客户端将cookie存储在本地

(2)用户再次访问服务器端,会在本次查找cookie,如果存在会自动加到请求头中

(3)服务器端通过cookie识别用户的身份,返回对应的请求资源

image.png

cookie的缺点

单个cookie的存储大小不能超过4kb,大小受到限制

安全性较低,cookie欺骗、cookie截获

有些状态不可能保存在客户端

每次访问都要携带cookie给服务器,浪费带宽

cookie数据有路径的概念,可以限制cookie只属于某个路径下

服务器端的session机制

session机制

当服务器收到请求需要创建session对象时,首先会检查客户端请求中是否有sessionId,如果有id,服务器根据该id返回对应的session对象。 如果客户端请求中没有session对象,服务器会创建新的session对象,并且把sessionId在本次响应中返回给客户端。 通常使用cookie的方式把sessionId存储到客户端,如果用户禁用了cookie,则要使用URL重写,当浏览器支持cookie时,url不做任何处理,当浏览器不支持cookie的时候,将会重写URL将sessionId拼接到访问地址之后。

session的安全性大于cookie

session存储在cookie,要攻破session先攻破cookie

sessionId要有人登录,或者启动session_start才会有,所以攻破也不一定得到sessionId

第二次启动session_start后,前一次的sessionId就失效了,session过期以后,sessionId也就消失了

sessionId是加密的

session的缺点

session保存的东西越多,就越占用服务器内存,对于在线人数比较多的网站,服务器的压力比较大

依赖cookie,如果不支持cookie,就要进行url重写,不安全

过度使用session变量会导致代码不可读而且不好维护

token原理

token的实现思路:

(1)客户端提供username和password登录系统,服务器端通过mysql数据库做判断,

(2)用户存在,服务器端生成token返回

(3)用户请求服务器端接口api时,携带token

(4)服务器进行检验,如果匹配,返回请求数据

(5)如果不匹配,返回错误代码

image.png

区别cookie、session、token

(1)用户第一次通过username和password登录系统,服务器通过Set-Cookie返回客户端,客户端将cookie保存在本地,之后访问接口api携带cookie即可,

思考💡:但是服务器是怎么认证cookie的?

其实在服务器返回Set-Cookie的信息里,有一个sessionId,服务器会在本地保存一份sessionId,当客户端携带cookie过来时,就对比cookie中的sessionid和服务器自己保存的sessionId就知道你是谁了,所以说cookie是有状态的

(3)但是新的问题出现了,对于客户端自己保存自己的cookie没有问题,但是服务器端要保存所有的sessionId,随着数据访问量增大,服务器就会出现性能问题

(4)通过token来解决上述问题,还是老样子,第一次访问,服务器发token,但是服务器不会再存储了,因为对token的加密只有服务器知道算法和密钥,所以再一次访问,服务器拿到信息,对信息进行token计算,算出的token 和携带的token对比,发现匹配,就返回资源,这样就解决了服务器的压力,所以说token是无状态的。

本地存储对比

(1)cookie

cookie存储大小是4kb;当没有设置cookie的过期时间时,cookie存储在内存中,生命周期随着窗口关闭结束,这种称为回话cookie;当设置cookie过期时间时,cookie存在硬盘中,关闭浏览器cookie存在,到过期时间才会消失;cookie在服务器和浏览器端来回传递,sessionStorage和localStorage只存在于本地;cookie中保存的是字符串;

(2)sessionStorage

sessionStroage的大小是5MB;成为会话存储,内容存储在内存中,当关闭浏览器会消失;保存的是键值对,但是存储之前需要使用JSON.stringify()将对象转换为JSON 字符串,当取出使用的时候,使用JSON.parse()将JSON 字符串转成对象

(3)localStorage

localStorage的大小是5MB;是本地存储,内容存储在硬盘中,当关闭浏览器的时候还存在,除非手动删除,不然不会消失

image.png

说一说cookie sessionStorage localStorage 区别?

得分点💥

数据存储位置、生命周期、存储大小、写入方式、数据共享、发送请求是否携带、应用场景

标准回答 💥

Cookie、SessionStorage、 LocalStorage都是浏览器的本地存储。

它们的共同点:都是存储在浏览器本地的

它们的区别:

cookie是由服务器端写入的,而SessionStorage、 LocalStorage都是由前端写入的,

cookie的生命周期是由服务器端在写入的时候就设置好的,LocalStorage是写入就一直存在,除非手动清除,SessionStorage是页面关闭的时候就会自动清除。

cookie的存储空间比较小大概4KB,SessionStorage、 LocalStorage存储空间比较大,大概5M。

Cookie、SessionStorage、 LocalStorage数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面。

在前端给后端发送请求的时候会自动携带Cookie中的数据,但是SessionStorage、 LocalStorage不会

加分回答 💥

由于它们的以上区别,所以它们的应用场景也不同,Cookie一般用于存储登录验证信息SessionID或者token,LocalStorage常用于存储不易变动的数据,减轻服务器的压力,SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能。

参考

彻底弄懂强缓存与协商缓存

[浏览器设置强缓存和协商缓存]

一文读懂http缓存

HTTP缓存机制