stale-while-revalidate=<seconds>
举例:Cache-control: max-age=10, stale-while-revalidate=60
(接口缓存10秒,swr设置为60秒)
mdn解释:表明客户端愿意接受陈旧的响应,同时在后台异步检查新的响应。秒值指示客户愿意接受陈旧响应的时间长度。
可以理解为:当该接口缓存过期后的60
秒(60秒为例子中的60)内,再次请求该接口,仍然会立刻返回已经过期的信息,同时也会调用接口向服务器获取最新的数据,并重新保存在缓存中。
为方便理解,stale-while-revalidate
可以总结为有三个特性:
swr
发生在缓存失效后(max-age
后)
swr
会在缓存失效后的一定时间内(swr
期间)的第一次请求,仍然会返回老数据
swr
期间请求接口,浏览器会发请求获取新数据,但不会在本次请求中返回(新数据)
基本流程如下图:
如果在swr期间请求接口:
swr
并不适用于大部分接口
首先swr
作为缓存的一种方式,肯定不适合高频更新的内容,如列表数据、详情信息等。
而且swr
会在缓存失效后一定时间内仍然返回老数据,虽然只有一次,但因为这个特性,也代表他不适合处理如banner获取、用户信息获取等接口,比如马上新年了,每个在运营的网站基本都会新年当天显示新年快乐的banner,但用户新年当天首次打开页面,却看不到新年祝福,就显得很奇怪。
所以,只适合一些更新频率低,而且对时效性不是很看重的接口,目前想到的只有广告展示这种接口比较适用。
stale-while-revalidate
目前仍然是实验性功能,并不是缓存标准文档的一部分,下边是它的兼容性(2024年1月截图)
想理解swr
到底是什么,建议大家都写一个demo试一试,文章底部我会提供一个接口,供大家练习测试
/swr
接口,请求头设置为:"Cache-Control": "max-age=10, stale-while-revalidate=10"
也就是说,该请求会缓存10秒钟,swr10秒钟
下边我对/swr
接口发起了多次请求:
首次请求:正常返回数据并记入缓存
在0~10s时间内请求:不向服务端发起请求,直接返回“首次”请求记入的缓存
第二次请求:直接返回“首次请求”记入的缓存,并向服务端发起请求(也就是请求Type
为text/html
的那次请求),重新把返回的数据记入缓存
后续请求,在10s内会返回“第二次请求”记入的数据,10s后,再请求会重复(3.)的动作
缓存设置为:"Cache-Control", "max-age=10, stale-while-revalidate=10"
为更直观的体验swr,接口会延时2秒返回
tips:个人服务器,接口可能并不稳定,不保证一直好用哦~
html文件内容(用跨域浏览器运行):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>test</title>
</head>
<body>
<h1 id="box"></h1>
<button id="button">请求</button>
</body>
<script>
// 请求
button.onclick = async () => {
const res = await fetch('https://blockxu.top/api/swr')
console.log('res', res)
// 获取返回内容
const text = await res.text()
box.innerHTML = text
}
</script>
</html>