有多种缓存方法。
有条件的GET
如果要将这些图像存储在文件系统上并直接通过Web服务器提供它们,则可能已经在使用条件get。Web服务器将自动使用文件系统元数据来设置ETAG标头,并且如果浏览器在其请求中包含标头If-Modified-Since
或If-Matches
标头,则会自动答复“ 304 Not Modified” 。(所有浏览器都可以。)
在这种情况下,不会退回整个图像,因此可以节省带宽。但是,仍然会发出GET请求,因此您仍然会有请求的开销和延迟。
您可以通过使Web服务器为图像设置Cache-Control
标头来稍微减少请求数,但会牺牲高速缓存的新鲜度public,max-age=N
。这表示缓存可以在最多max-age
检查资源是否更新之前将其保留最多几秒钟。
但是,HTTP仅定义了一种使缓存条目无效的方法,该方法可能不符合您的应用程序的语义:如果将POST或PUT张贴到更新个人资料照片的url,则回复Location: [url of photo]
标头,并且该URL的缓存条目将无效。
(通过这种机制,您可以缓存带有评论的网页,然后在用户发布新评论后由浏览器强制重新加载该页面。浏览器将回复POST /comment
带有303 See Other
和的Location: /page/with/comment
。请注意,这并未使用由于存在长期的错误而无法在Firefox中使用。)
除非您有很多流量,否则这种缓存方法很好。
更改网址
url是资源的表示形式,因此管理缓存的另一种方法不是更改资源的缓存参数,而是使用“永远缓存”指令来创建全新的资源。这是该方法的“大男孩”的青睐,因为它可以让他们产生任何额外的要求,为他们节省大量的带宽。缺点是它需要更多的簿记。
有两种通用技术。
查询字串
当从文件系统提供文件服务时,Web服务器将忽略查询字符串。但是,缓存不会:/1.jpg?t=12345
并且/1.jpg?t=67890
是两个完全不同的,不相关的资源,即使服务器认为它们是相同的。
因此,您可以做的一件简单的事情就是,每当您对html中的资源进行引用时,将文件系统时间戳记附加为查询字符串,并设置一个长Expires
标头。然后,浏览器将永远缓存此资源,并且只要查询字符串不变,就不会执行任何 GET。
缺点是,如果您想强制使缓存无效,则很难或不可能向网络服务器指示项目的新url。例如,如果浏览器的缓存HTML页面带有/1.jpg?v=1
引用,但碰巧清除了该条目/1.jpg?v=1
(可能是文件或内存空间不足),它将向发送新请求/1.jpg?v=1
。如果在此期间图像已更改为/1.jpg?v=2
,则正确的响应是:
- 服务文件的旧版本。如果您希望所有资源在某个时间点都保持一致,则可以执行此操作。例如,这是您应该对CSS文件执行的操作,因为带有旧html文件的新css文件可能无法正常工作!
- 使用重定向到文件的新版本
301 Moved Permanently
。如果您希望所有资源尽可能新,则可以这样做。
单独使用Web服务器很难做到这两者,这意味着即使是图像请求,您也需要调用Web应用程序,这可能更加复杂,而且会占用更多资源。Web 服务器提供文件的速度非常快,因此Web应用程序的开销可能最终吞噬了带宽和延迟。
档案名称
更改文件名,而不是添加查询字符串。这意味着在文件系统上保留多个版本的文件很容易,但是您可能需要存储文件元数据并进行其他数据库记账以跟踪您的资源及其名称。