上一篇文章,我们讲到了使用AWS云托管静态资源,现在我们提出一个特殊的场景来做案例研究.
我们有一个需求: 客户端需要一种非常简便的方式来判断自己本地的静态资源和云端CDN的不一致了,也就是CDN的内容更新后客户端能知道产生了本次更新并及时的下载最新的内容.
问题: 怎么保证客户端数据是最新的?
解决方式 很可能有这个方案:
- 设计一个API,APP通过某种规则(轮询/定时/每次进入界面...)请求这个API获取最新的文件版本号并和本地预先记录的版本相对比,不一致则下载最新的文件.
- 设计一个WebSocket,做长连接通知,当云端的数据发生变化了就通知客户端
上面的2种方式理论上是可行的,但是实际上开发成本和交互逻辑比较繁琐.
这里介绍一种更加简单的方式: 使用If-None-Match来做版本对比
时许图如下:
它的核心原理是: 每次HTTP get请求CDN资源的时候,都带上If-None-Match
hdeader参数并给他填入etag
的值,如果request里面的值和云端的对不上,就说明发生了内容变更,那么就返回200
并传输变更后的文件内容给客户端;如果request的值和云端的对的上,那么就返回304
表示内容一致,无需重新下载内容; 首次请求时如果你没有etag
可以不填或者填写一个固定的无意义的占位值,这样依然可以下载全新内容.
我们以AWS CloudFront的为例进行演示:
首先我有一个cloudfront缓存的资源,使用浏览器访问时返回的消息如下:
我们可以看到etag
和last-modified
字段,ETag能标示URL对象是否改变,你可以理解为类似于文件的MD5校验码, Last-modified 是服务器端文件的最后修改时间. 我们在header的If-None-Match
里面填入etag
,那么就可以让云端的服务判断是否需要把新的内容返回给客户端.
我们以postman演示
如果 If-None-Match
, 为真,那么说明etag
不一致,需要下载内容
如果
If-None-Match
, 为假,那么说明etag
一致,不需要下载内容
参考: