缓存头 Cache-Control 的含义和使用

本篇我们来写一下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.

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值