强缓存和协商缓存

1、浏览器缓存
1,第一次请求,无缓存请求过程
         
流程以下所示
第二次请求,有缓存请求的过程
          
 
流程以下图所示
浏览器的缓存分为二种,第一种的是强缓存,另一种是协商缓存
2 :强缓存
定义:强缓存在请求资源的时候,会从header里面读取是不是强缓存,在有效的时间时间期内,从缓存里读取不能从服务那里读取

介绍使用:javascript

expires,这是http1.0时的规范;它的值为一个绝对时间的GMT格式的时间字符串,如Mon, 10 Jun 2015 21:31:12 GMT,若是发送请求的时间在expires以前,那么本地缓存始终有效,不然就会发送请求到服务器来获取资源html


cache-control:的含义和使用
可缓存性属性说明
pubilc:http只要通过的地方都要进行缓存
privite:发出的浏览器端要进行缓存
no-cache:本地能够有缓存,须要服务器验证才可使用
no-store:本地和服务器都没有缓存
max-age=<seconds> :缓存的最大的时间
3,代码案例分析:
1,简单的建立一个服务
const http = require('http');
const fs = require('fs');
// 建立一个http服务
http.createServer((request, response) => {
console.log('request-url' + request.url);
if (request.url === '/') {
const html = fs.readFileSync('test.html', 'utf8');
response.writeHead(200, {
'Content-Type': 'text/html',
})
response.end(html);
}
if (request.url === '/script.js') {
// const html = fs.readFileSync('test.html', 'utf8');
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-control': 'max-age=200 ',
})
response.end('ffff');
}
}).listen(8888);
4,解决的方法呢:

上面说到,使用强缓存时,浏览器不会发送请求到服务端,根据设置的缓存时间浏览器一直从缓存中获取资源,在这期间若资源产生了变化,浏览器就在缓存期内就一直得不到最新的资源,那么如何防止这种事情发生呢?前端

经过更新页面中引用的资源路径,让浏览器主动放弃缓存,加载新资源。java

前端经常后面加上版本号和一些hash值从新的读取api

    

2、介绍协商缓存
    协商缓存都是由服务器来肯定缓存资源是否可用的,因此客户端与服务器端要经过某种标识来进行通讯,从而让服务器判断请求资源是否能够缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段
     
  1. Last-Modified/If-Modified-Since
    两者的值都是GMT格式的时间字符串,具体过程:
    • 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Last-Modified的header,这个header表示这个资源在服务器上的最后修改时间
    • 浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值
    • 服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,若是没有变化则返回304 Not Modified,可是不会返回资源内容;若是有变化,就正常返回资源内容。当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header,由于既然资源没有变化,那么Last-Modified也就不会改变,这是服务器返回304时的response header
    • 浏览器收到304的响应后,就会从缓存中加载资源
    • 若是协商缓存没有命中,浏览器直接从服务器加载资源时,Last-Modified的Header在从新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值
  2. Etag/If-None-Match
    这两个值是由服务器生成的每一个资源的惟一标识字符串,只要资源有变化就这个值就会改变;其判断过程与Last-Modified/If-Modified-Since相似,与Last-Modified不同的是,当服务器返回304 Not Modified的响应时,因为ETag从新生成过,response header中还会把这个ETag返回,即便这个ETag跟以前的没有变化。

 三、既生Last-Modified何生Etag
  你可能会以为使用Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为何还须要Etag呢?HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
  • 一些文件也许会周期性的更改,可是他的内容并不改变(仅仅改变的修改时间),这个时候咱们并不但愿客户端认为这个文件被修改了,而从新GET;
  • 某些文件修改很是频繁,好比在秒如下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改没法判断(或者说UNIX记录MTIME只能精确到秒);
  • 某些服务器不能精确的获得文件的最后修改时间。
这时,利用Etag可以更加准确的控制缓存,由于Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的惟一标识符。
Last-Modified与ETag是能够一块儿使用的,服务器会优先验证ETag,一致的状况下,才会继续比对Last-Modified,最后才决定是否返回304

4,代码案例浏览器

if (etag === '777') {
response.writeHead(304, {
'Content-Type': 'text/javascript',
'Cache-control': 'max-age=200000,no-cache',
'last-Modified': '123',
'Etag': '777',
})
response.end('');
} else {
response.writeHead(200, {
'Content-Type': 'text/javascript',
'Cache-control': 'max-age=200000,no-cache',
'last-Modified': '123',
'Etag': '777',
})
response.end('fffff');
}

 

3、强缓存与协商缓存的区别,能够用下表来进行描述:缓存

 

  获取资源形式 状态码 发送请求到服务器
强缓存  从缓存取  200(from cache) 否,直接从缓存取
协商缓存  从缓存取  304(not modified) 是,正如其名,经过服务器来告知缓存是否可用
相关文章
相关标签/搜索