HTTP(Ⅵ)—— 缓存验证Last-Modified和Etag的使用

一、先看一张图

浏览器创建一个请求,然后请求到达本地缓存,如果找到了则直接返回给浏览器,如果没有,可能会经过代理服务,然后去代理缓存中去找,如果命中,则直接返回,如果没有,才会到源服务器进行请求。

二、数据如何进行验证,有两个头。

1、Last-Modified上次修改时间,它配合If-modified-Since和If-Unmodified-Since使用。如果我们请求一个资源,这个资源返回的有Last-Modified。浏览器进行下一次请求的时候,,通过If-modified-Since或If-Unmodified-Since把Last-Modefied的值带到服务器上,服务器通过读取If-modified-Since的值然后对比资源存在的地方,然后去对比上次修改的时间,如果时间是一样的,代表这个资源还没有重新被修改,服务武器告诉浏览器可以使用缓存里面的内容

2、Etag数据签名,我们的资源对他的内容会产生唯一的签名,只要修改,签名就会改变,最常见的就是对资源内容进行哈希计算,浏览器下一次请求,通过If-Match或If-Non-Match把Etag的值带到服务器上,然后服务器对比浏览器传过来的签名和服务器端资源的签名是否一致,如果相同,就不需要返回一个心的内容。

三、测试

1、修改server.js如下:

const http = require('http')
const fs = require('fs')
http.createServer(function(request, response) {
    console.log('request come', 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=2000000, no-cache',
			'Last-Modified': '123',
			'Etag': '777'
        })
        response.end('console.log("script loaded twice")')
	}
}).listen(8888)
console.log('server listening on 8888')

2、重启服务刷新浏览器

3、再刷新浏览器,结果可以看到,它还是去访问了服务器。

它的Requset Headers显示如下:

它的repsonse里面是有内容的,的但是我们的内容没有做更改,我们这时只需要告诉浏览器不需要返回实际的内容,只需要去读取缓存就好了。这时我们可以将server.js修改为如下:

const http = require('http')
const fs = require('fs')
http.createServer(function(request, response) {
    console.log('request come', 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=2000000, no-cache',
			'Last-Modified': '123',
			'Etag': '777'
        })
		const etag = request.headers['if-none-match']
		if(etag  === '777'){
        	response.writeHead(304, {
                'Content-Type': 'text/javascript',
                'Cache-Control':'max-age=2000000, no-cache',
                'Last-Modified': '123',
                'Etag': '777'
			})
			response.end(' ')
		} else {
            response.writeHead(200, {
                'Content-Type': 'text/javascript',
                'Cache-Control':'max-age=2000000, no-cache',
                'Last-Modified': '123',
                'Etag': '777'
            })
		}
        response.end('console.log("script loaded twice")')
	}
}).listen(8888)
console.log('server listening on 8888')

然后再此刷新会看到如下界面,304表示的就是从缓存里面读取内容。如果将上述的no-cache去掉,结果和之前一样,但是如果将no-cache换成no-store,就不会和缓存有任何关系,每次发送请求都会认为那是一个全新的请求,去请求成功,返回200。

猜你喜欢

转载自blog.csdn.net/zhanghuali0210/article/details/82081113