讲讲浏览器的缓存机制

news/2024/5/19 1:08:02 标签: 浏览器缓存, 协商缓存, 流程图

问题的开端是由http响应状态码304引出的!

一般而言,第一次访问一个网站,返回的状态码是200。那304状态码有什么用?

这跟浏览器性能优化分不开。

例如,浏览器直接使用缓存而不发起请求,减少请求;或者发出了请求,但服务器和浏览器资源一致,没有发生改变,这时候就没必要将数据再传一次,这样一来减少了数据传输(返回304和一个空的响应体),减轻了服务器的压力。

附一张浏览器缓存流程图:(仿别人用ProcessOn工具画的)

<a class=浏览器缓存流程图" class="has" height="900" src="https://img-blog.csdnimg.cn/20190327203438583.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI3OTU0NjQz,size_16,color_FFFFFF,t_70" width="680" />

看完流程图,别慌。了解一下上面提到几个单词。

Last-Modified和If-Modified-SinceEtag和If-None-Match这两组header字段都是成对出现,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或Etag字段,则后续请求头也不会有对应字段。

为什么既有Last-Modified还有Etag,这两者功能不是一样的吗?

你可能会觉得使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag呢?

http1.1中Etag的出现主要是为了解决Last-Modified难解决的问题:

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅修改文件时间),这个时候我们并不希望客户端认为这个文件被修改了,而需要重新发送get请求;
  • 某些文件修改非常频繁,比如1s内修改了N次,而If-Modified-Since能检查到的时间粒度是秒级的,其结果是无法判断这种修改结果;
  • 某些服务器不能精确得到文件的最后修改时间。

这时,利用Etag能够更加准确地控制缓存,因为Etag是服务器自动生成的对应资源在服务器端的唯一标识符。

浏览器怎么根据If-Modified-Since和If-None-Match决定返回304还是200状态码?

第一次请求, 服务器端返回ETag:"50b1c1d4f775c61:df3";第二次请求同一资源,客户端发送一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d044840;如果ETag没有改变,说明资源没有被修改,服务器返回状态304和空的响应体;

第一次请求,浏览器在response header中添加 Last-Modified,值是这个资源在服务器上的最后修改时间;浏览器下一次请求这个资源,浏览器检测到有 Last-Modified这个header,于是添加If-Modified-Since这个header,值就是Last-Modified中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取;如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200状态码。

Etag定义可以好好看下百度百科:https://baike.baidu.com/item/ETag/4419019?fr=aladdin

推荐这个人,有浏览器实际缓存操作:https://www.cnblogs.com/softidea/p/5986339.html


http://www.niftyadmin.cn/n/1426104.html

相关文章

JavaScript——旋转数组的最小数字

题目描述 把一个数组最开始的若干个元素搬到数组的末尾&#xff0c;我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转&#xff0c;输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转&#xff0c;该数组的最小值为1。 NOTE&#xff1a;给出的所有…

jsp防sql注入

在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement.基于以下的原因:一.代码的可读性和可维护性.虽然用PreparedStatement来代替Statement会使代码多出几行,但这样的代码无论从可读性还是可维护性…

JavaScript——菲波那切数列

题目描述 大家都知道斐波那契数列&#xff0c;现在要求输入一个整数n&#xff0c;请你输出斐波那契数列的第n项&#xff08;从0开始&#xff0c;第0项为0&#xff09;。 n<39 function Fibonacci(n) { //自己的方法/*if(n0) return 0;if(n1) return 1;var count1;var …

JavaScript——青蛙跳台阶

题目描述 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法&#xff08;先后次序不同算不同的结果&#xff09;。 function jumpFloor(number) {// write code here//自己先写几个&#xff0c;多少台阶几种跳法。属于找规律…

JavaScript——变态跳台阶

题目描述 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 function jumpFloorII(number) {// write code here//青蛙跳台阶的plus版&#xff0c;同样从一个台阶开始&#xff0c;手动计算有多少种跳…

找规律——矩形覆盖

题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形&#xff0c;总共有多少种方法&#xff1f; 对问题进行分析&#xff1a; 得出规律 &#xff1b; function rectCover(number) {// write code here//从n…

源码研究

程序采用自动安装程序&#xff0c;把所有CGI文件和HTML目录及其下面的文件上传到CGI-BIN目录下&#xff0c;并保持它的原结构&#xff0c;图片文件请不要放在CGI-BIN目录下&#xff0c;把cgi文件属性改为755&#xff0c;然后执行install.cgi首页调用代码&#xff1a;<script…

查询自己主机的IP地址和WWW服务的IP地址

例如要取得 www.126.com的IP String ipjava.net.InetAddress.getByName("www.126.com").toString(); //取得指定的web主机的IP 自已的ip. <%request.getRemoteAddr()%>