HTTP缓存异常是指在客户端和服务端交互过程中,由于缓存机制不当,导致客户端获取到的资源和服务端实际的资源不一致,或者客户端获取到的资源已经过期,需要重新请求服务端获取最新的资源。HTTP缓存异常的原因主要有以下两点:
- 缓存头部信息不正确
HTTP缓存是通过HTTP头部信息来控制的,如果头部信息不正确,则会导致缓存异常。例如,如果 Cache-Control
头部信息被设置为 no-cache
,则每次请求资源时都会重新向服务器请求资源,而不是使用缓存的资源。如果服务器返回的 Cache-Control
头部信息没有设置为 max-age
或者 Expires
,则缓存的有效期会非常短,容易使得缓存失效。
下面是一个设置缓存头部信息的示例:
HTTP/1.1 200 OK
Date: Mon, 30 Jan 2017 09:05:22 GMT
Server: Apache/2.2.10
Last-Modified: Mon, 23 Jan 2017 13:27:08 GMT
ETag: "20f7402b-2c0-528b8f2399169"
Content-Length: 704
Cache-Control: max-age=3600
Expires: Mon, 30 Jan 2017 10:05:22 GMT
Content-Type: text/html
在这个示例中,服务器返回的缓存头部信息包括了 Cache-Control
和 Expires
,指示浏览器可以缓存该资源并保持缓存1小时,在1小时之内再次请求资源时,浏览器可以从本地缓存中读取资源。
- 缓存标识不唯一
缓存标识用于标识缓存的唯一性,如果不唯一,则可能出现缓存异常。例如,如果服务端返回的 ETag
值不唯一,客户端就无法正确判断缓存是否过期,从而导致浏览器需要重新从服务端请求资源。同时,如果服务端返回的 Last-Modified
值也不唯一,客户端也无法正确判断资源是否过期。
以下是一个使用 ETag
和 Last-Modified
来进行缓存的示例:
HTTP/1.1 200 OK
Date: Mon, 30 Jan 2017 09:05:22 GMT
Server: Apache/2.2.10
Last-Modified: Mon, 23 Jan 2017 13:27:08 GMT
ETag: "20f7402b-2c0-528b8f2399169"
Content-Length: 704
Cache-Control: max-age=3600
Expires: Mon, 30 Jan 2017 10:05:22 GMT
Content-Type: text/html
在这个示例中,服务端返回的 ETag
是 "20f7402b-2c0-528b8f2399169"
标识了该资源的唯一性,在浏览器下次请求该资源时,请求头部信息中包含了 If-None-Match
字段,该字段的值就是 ETag
的值。如果该值和服务器中缓存的资源的 ETag
值一致,服务端就会返回 304 Not Modified,通知浏览器从本地缓存中读取资源。
在这个示例中,服务端也返回了 Last-Modified
头部信息,用于较早的浏览器兼容,如果服务器觉得 ETag
不方便设置,也可以设置 Last-Modified
头部信息,只要通过使用 If-Modified-Since
序头检查该信息,并使用 If-Modified-Since
的值执行条件 GET 请求即可。
综上所述,HTTP缓存异常的原因主要在于缓存头部信息的设置不当、缓存标识不唯一等方面。为了避免缓存异常,我们需要合理的设置缓存头部信息并保证缓存标识的唯一性。