赞
踩
本篇我们来写一下HTTP 中的缓存,即Cache-Control 。
Cache-Control 的可缓存性(指明哪些地方可以缓存返回的数据):
- public (HTTP 返回的时候在Heaher 中设置Cache-Control 的值为‘public’。它代表,这个HTTP 请求它返回的内容所经过的任何路径中,包括中间的一些HTTP 代理服务器以及发出请求的客户端浏览器,都可以进行对返回内容的缓存操作)
- private (发起请求的浏览器才能使用返回数据的缓存)
- no-cache (可以在本地或者proxy服务器进行缓存,每次发起请求都要去服务器验证,服务器返回可以使用缓存,才可以真正使用本地缓存,任何节点都不能直接使用缓存)
到期(缓存的有效期)
max-age=<seconds> (最常用)
s-maxage=<seconds>(只有在代理服务器才会生效,且代理服务器会优先使用s-maxage)
max-stale=<seconds> (它是发起请求方,主动去带着的header;在max-age过期后,但还在max-stale的有效期内,还可以使用过期的缓存,不需要去原服务器请求新的内容)
重新验证(不常用)
must-revalidate (它的意思是:当我们设置了 max-age ,过期后,我们必须去原服务端发送请求,重新获取数据,验证是否缓存过期,而不能直接去使用本地的缓存)
proxy-revalidate (与must-revalidate 相似,proxy-revalidate 是用在缓存服务器中,如果缓存服务器中的数据过期的话,需要去原服务器发送请求...)
其他
no-store (浏览器或者proxy服务器都不能存返回数据的缓存,永远都需要去服务器请求新的数据)
no-transform (主要用在proxy服务器,表示不要去随意改动返回的内容,比如压缩什么的)
下面我们来试一试max-age,如下。
先是 server.js 代码
- const http = require('http')
- const fs = require('fs')
-
- http.createServer(function (request, response) {
- console.log('request come', request.url)
-
- const html = fs.readFileSync('test.html', 'utf8')
- response.writeHead(200, {
- 'Content-Type': 'text/html'
- })
- response.end(html)
- }).listen(8888)
-
- console.log('serve listening on 8888')
然后test.html 代码如下
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>MyHtml</title>
- </head>
- <body>
- <div>hello world</div>
- <div>don't speak</div>
- <script src="/script.js"></script>
- </body>
- </html>
然后,启动服务。在浏览器输入URL localhost:8888 就可以访问,如下。
有了上面的基础后,我们给/script.js 请求添加max-age 为20s 如下。
- 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('testMaxAge.html', 'utf8')
- response.writeHead(200, {
- 'Content-Type': 'text/html'
- })
- response.end(html)
- }
-
- if (request.url === '/script.js') {
- response.writeHead(200, {
- 'Content-Type': 'text/javascript',
- 'Cache-Control': 'max-age=20'
- })
- response.end('console.log("script loaded")')
- }
- }).listen(8888)
-
- console.log('serve listening on 8888')
下面,我们重启服务后,刷新页面,第二次刷新(间隔小于20s)时,会发现/script.js 是从缓存中读的。如下。
但是,有一个问题 catch-control 是客户端缓存,当max-age 之内,服务端更新了数据,客户端是不能知道的。
这个问题,前端的一种常用的解决方案是,将打包的js文件名加入一段哈希码,当打包内容不变时,哈希码就不变。这样子,当内容不变时,请求的url 也就不变,当内容变了请求的url 也变了。这样就达到了更新缓存的目的。
最后,catch-control 有很多值,之间使用逗号分割即可,如下。
- 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('testMaxAge.html', 'utf8')
- response.writeHead(200, {
- 'Content-Type': 'text/html'
- })
- response.end(html)
- }
-
- if (request.url === '/script.js') {
- response.writeHead(200, {
- 'Content-Type': 'text/javascript',
- 'Cache-Control': 'max-age=20, public'
- })
- response.end('console.log("script loaded")')
- }
- }).listen(8888)
-
- console.log('serve listening on 8888')
Done.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。