强制缓存:
(1)HTTP响应报文中expires的时间值,是一个绝对值
(2)HTTP响应报文中Cache-Control为max-age=600,是相对值
由于Cache-Control的优先级比expires高,那么直接根据Cache-Control的值进行缓存,意思就是说在600秒内再次发起该请求,则会直接使用缓存结果,强制缓存生效。
在无法确定客户端的时间是否与服务端的时间同步的情况下,比如手动修改了客户端的时间,Cache-Control相比于expires是更好的选择,所以同时存在时,只有Cache-Control生效。
在现代的 Web 开发中,Cache-Control
通常比 Expires
更常用,因为它提供了更灵活的缓存控制机制,并且不受时钟同步的问题影响。绝大多数情况下,建议使用 Cache-Control
头部来定义缓存策略。
协商缓存:
1:ETag和Last-Modified
1)客户端第一次请求,服务端会计算出资源的ETag值,包含在返回头里面返回给客户端
2)客户端保存该资源相对应的ETag值,当下一次再次请求该资源的时候,将该Etag值赋值到请求报文头的If-Modified-Since发送给服务端
3)服务端得到该Etag值,再计算当前该资源得到新的ETag2,比较两个ETag值,如果不变,返回304,客户端使用缓存的资源。如果两个值不同,说明服务端的资源已经改变,这时候返回200以及新的资源。
2:Last-Modified(Etag的优先级比Last-Modified高)
1)服务端返回的资源具有Last-Modified声明,则再次向服务端请求时带上头 If-Modified-Since,表示请求时间。
2)服务端收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache
https://blog.csdn.net/qq_39339575/article/details/109682737
在实际应用中,ETag
和 Last-Modified
都被广泛使用,但它们在一些场景下可能有一些不同的特点。
常用情况:
-
ETag:
- 优势:
- 更精准:由服务器生成的哈希值通常更精准地表示资源的状态,因此在资源内容发生变化时,
ETag
更容易识别变化。
- 可用于任何资源:
ETag
可以用于任何类型的资源,不仅仅是基于文件的资源。
- 劣势:
- 计算开销:生成哈希值可能需要一些计算开销,尤其是对于大型文件。
-
Last-Modified:
- 优势:
- 简单:
Last-Modified
使用资源的最后修改时间,比较简单直观,且不需要像哈希计算那样的开销。
- 文件系统支持:对于基于文件的资源,文件系统通常会记录最后修改时间,这使得
Last-Modified
更容易实现。
- 劣势:
- 时间精度:某些系统可能只提供有限的时间戳精度,这可能导致在非常短的时间内进行多次修改的资源无法被准确识别。
综合考虑:
- 在大多数情况下,
ETag
更为常见,特别是对于大型、动态生成的内容或者对精确性要求较高的场景。
Last-Modified
仍然被广泛使用,尤其是对于基于文件的静态资源,因为文件系统通常会记录修改时间,而且它的实现更为简单。
在实际开发中,通常会同时使用这两者,以确保更好的兼容性和性能。例如,浏览器在发送请求时可能同时包含 If-None-Match
(用于 ETag
)和 If-Modified-Since
(用于 Last-Modified
),服务器则可以根据情况选择使用其中之一来判断是否返回 304 Not Modified 响应。
last-modified:为什么时间戳会有精度问题:
时间戳精度问题可能出现在某些文件系统中,这些文件系统的设计可能限制了文件最后修改时间戳的精度。在一些操作系统中,文件系统可能只能以秒为单位记录文件的最后修改时间。
这种精度限制可能导致以下情况:
-
多次修改在同一秒内:如果一个文件在相同的一秒内进行多次修改,这些修改可能无法被准确地反映在 Last-Modified
头部中。这是因为文件系统的时间戳可能只能表示到秒,无法区分同一秒内的多个修改。
-
并发操作问题:在高并发环境下,多个用户或进程可能在相同的时间内修改同一文件。由于时间戳的限制,这些并发操作可能无法准确地记录在 Last-Modified
中,从而影响缓存的准确性。
-
时间戳回绕问题:某些文件系统可能对时间戳有一个上限,当文件经历了足够多的修改后,时间戳可能回绕到较早的时间。这可能导致在某一瞬间内的多个修改被错误地认为是相同的修改。
这些问题在实践中可能并不总是严重的,特别是对于静态资源或不太频繁修改的文件。然而,为了更准确地处理缓存,特别是对于动态内容或需要高精度缓存控制的情况,使用 ETag
通常是更可靠的选择,因为它不受文件系统时间戳精度的限制。
强制缓存和协商缓存的对比:
强制缓存和协商缓存在实际应用中都有广泛使用,但它们通常用于不同的场景和目的。哪种方式更常用取决于开发者的需求以及具体的应用场景。
-
强制缓存:
- 优势:
- 简单快速:强制缓存通过在响应头中设置
Cache-Control
或Expires
,告诉浏览器在一段时间内直接使用缓存,而不需要再次请求服务器。
- 减少服务器负载:由于客户端直接使用本地缓存,减少了对服务器的请求,降低了服务器负载。
- 劣势:
- 不适用于动态内容:对于频繁变化的动态内容,使用强制缓存可能不够灵活,因为它要求在指定的时间内不更新缓存。
-
协商缓存:
- 优势:
- 灵活性:协商缓存通过使用
ETag
和Last-Modified
头部,允许服务器在资源未发生变化时告知客户端直接使用缓存,而在资源发生变化时提供新的内容。
- 适用于动态内容:对于动态生成的内容或需要更精确控制缓存的情况,协商缓存是一个更好的选择。
- 劣势:
- 需要进行比较:协商缓存需要服务器进行一些额外的比较工作,以确定是否返回 304 Not Modified 响应,这可能会增加服务器的负载。
综合考虑:
- 在许多场景下,开发者会同时使用强制缓存和协商缓存,以充分利用它们的优势,提高性能和用户体验。
- 对于静态资源或者不太频繁变化的内容,强制缓存是一个简单而有效的策略。
- 对于动态内容或者需要更灵活的缓存控制的情况,协商缓存通常更为适用。