HTTP中客户端和服务端如何确认内容是否已修改?
为效率的提高,数据的传输要避免重复,所以就采用了缓存的方法。
但是可能出现一个问题,那就是当源数据变化时,应该及时感知这种变化,否则还用过时的版本的数据,就会出问题,
为了追求效率,而造成麻烦(出现功能问题),这是不应该被允许的。
那么HTTP里是如何保证内容修改后让大家及时感知呢?有下面这些方法,这些方法也是有利有弊,在发展中不断完善的。
在 RFC2616 中有相应的定义,比如实现 Last-Modified 来标识文件的最后修改时间,这样即可判断出续传文件时是否已经发生过改动。
在RFC2616 中还定义有一个 ETag 的头,可以使用 ETag 头来放置文件的唯一标识。
If-Modified-Since,和 Last-Modified 一样都是用于记录页面最后修改时间的 HTTP 头信息。
Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since 则是由客户端往服务器发送的头。
再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了。
Etag(Entity Tags)解决了 Last-Modified 存在的一些问题。
- 一些文件也许会周期性的更改,但是内容并不改变(仅改变修改时间),这时候我们并不希望客户端认为这个文件被修改了,而重新 GET。
- 某些文件修改非常频繁,例如:在秒以下的时间内进行修改(1s 内修改了 N 次),If-Modified-Since 能检查到的粒度是 秒 级的,这种修改无法判断(或者说 UNIX 记录 MTIME 只能精确到秒)。
- 某些服务器不能精确的得到文件的最后修改时间。
为此,HTTP/1.1 引入了 Etag。Etag 仅仅是一个和文件相关的标记,可以是一个版本标记,例如:v1.0.0;或者说 “627-4d648041f6b80” 这么一串看起来很神秘的编码。但是 HTTP/1.1 标准并没有规定 Etag 的内容是什么或者说要怎么实现,唯一规定的是 Etag 需要放在 “” 内。
- 点赞
- 收藏
- 关注作者
评论(0)