缓存的策略,一旦确定并下发到客户端,服务端就失去了对齐的控制权。也就是说,如果我们设定了 max-age,在此资源有效期超时之前,哪怕服务端的源资源已经被替换修改,我们也没有一个合适的时机去通知客户端更新新的响应数据。
那么有没有什么好的策略去标记资源废弃?同时又能友好的利用缓存策略。
在互联网上,所有服务上的资源,都有一个对应的 URL(统一资源定位符),它可以明确说明如何从一个精确且固定的位置获取资源。而 HTTP 缓存,也是依赖于 URL 的,注意 URL 是大小写敏感的,同一个 URL 表示同一个请求响应,依此来判断缓存和后续缓存的复用。
所以我们是可以在 URL 上做文章的。
4.1 浏览器的废弃策略前面提到,浏览器是天然支持 HTTP 缓存的,对于浏览器来说,它所面对的就是一个个 HTML 页面,页面内会包含一些 CSS、Image、JavaScript、JSON 资源和数据。
针对不同的资源和数据,我们可以在其 URL 上,增加数据令牌指纹,当资源变动的时候,同时也去刷新改指纹令牌。
到这里就很好理解了:
HTML 页面,使用 no-cache,强制每次都向源服务器确认数据。
CSS文件通常变动的频率非常低,所以可以允许中间层缓存,并且缓存时间为一年不过期。
JavaScript内有业务逻辑,可以设定为只允许客户终端缓存。
getUserInfo,是为个人用户数据相关,这里推荐可缓存,但是需要每次向服务器重新确认。
4.2 App 接口的缓存策略在 App 中使用的接口,其实和网页又不一样,HTML 网页的结构类似一个树形结构,先通过获取 .html 文件获取其内所有资源的表,然后依次根据缓存策略进行访问。
但是在 App 中,和服务器的交互都是通过数据接口来实现的,就不存在最开始获取一个类似 HTML 文件这样的树形接口,每个接口都是一个个“孤岛”,可以单独存在。我们就无法提前知道某个接口的响应数据已经过期,同时也无法修改 URL 上携带的数据指纹令牌。
但是其实我们是可以通过 App 和设备的一些固有信息,作为 URL 的参数传递,以此来刷新数据。
例如这里 /app/main 获取主页的数据,这里将当前 App 的版本号当参数拼接在 URL 的后面,以此方式来强制不同的版本,刷新不同的数据。避免刚升级上来的 App,还在使用旧版本的数据。
这个例子中,版本号只是其中一个维度,如果有必要,还可以传递其他维度的信息,例如当前网络状态,当前用户 id 等等。
五、小结到这里我们基本上把 HTTP 的缓存所有相关的内容都讲了一遍,这里简单总结一下。
HTTP 缓存依赖 URL 做唯一标识,不同的 URL 使用不同的缓存。
Cache-Control 可以控制缓存策略,共有或者私有、缓存超时时长等。
通过 ETag 来标记数据指纹令牌,以此来确定响应数据是否更新。
应该为每个响应资源提供对应的缓存策略。
如果需要废弃之前的缓存,可以利用修改请求 URL 的方式,将数据指纹令牌追加在 URL 之后,以此来更新数据。
关于 HTTP 缓存,你还有什么更好的想法,可以在留言区讨论。
参考资料:
《HTTP缓存》:
《基于缓存策略三要素分解法》
公众号后台回复成长『成长』,将会得到我准备的学习资料,也能回复『加群』,一起学习进步;你还能回复『提问』,向我发起提问。
推荐阅读: