1) 什么是”Last-Modified”?
在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:
Last-Modified: Fri, 12 May 2006 18:53:33 GMT
客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:
If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT
如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。
2) “Etag”
我们都知道,HTTP/1.1中有一个Etag,用来判断请求的文件是否被修改。为什么要使用Etag呢?Etag主要为了解决Last-Modified无法解决的一些问题
1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
3、某些服务器不能精确的得到文件的最后修改时间;
为此,HTTP/1.1引入了Etag(Entity Tags)。Etag仅仅是一个和文件相关的标记,可以是一个版本标记,比如说v1.0.0或者说”2e681a-6-5d044840″这么一串看起来很神秘的编码。但是HTTP/1.1 标准并没有规定Etag的内容是什么或者说要怎么实现,唯一规定的是Etag需要放在“”内。
Etag由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。我们常见的是使用If-None-Match.请求一个文件的流程可能如下:
====第一次请求===
1.客户端发起HTTP GET请求一个文件;
2.服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如”2e681a-6-5d044840″)(假设服务器支持Etag生成和已经开启了Etag). 状态码200
====第二次请求===
1.客户端发起HTTP GET请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是我们第一次请求时服务器返回的Etag:2e681a-6-5d044840
2.服务器判断发送过来的Etag和计算出来的Etag匹配,因此If-None-Match为False,返回304,客户端继续使用本地缓存;
流程很简单,问题是,如果服务器又设置了Cache-Control:max-age和Expires呢,怎么办?
答案是同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.(不要陷入到底使用谁的问题怪圈)
Etag分strong etag和weak etag,如果两个entity的strong etag是匹配的,那么这两个entity的每个byte都是一样的。weak etag只是保证在语义上的一致性,并不能保证两个entity是否每个byte都一样。弱Etag以W/开始,比如:W/”2e681a”
在apache中,强Etag 根据配置文件中的配置来设置Etag值,默认的Apache的FileEtag设置为:
FileEtag INode Mtime Size
也就是根据这三个属性来生成Etag值,他们之间通过一些算法来实现,并输出成hex的格式,相邻属性之间用-分隔,比如:
Etag “2e681a-6-5d044840″
这里面的三个段,分别代表了INode,MTime,Size根据算法算出的值的Hex格式,(如果你在这里看到了非Hex里面的字符(也就是0-f),那你可能看见神了:))
当然,我们可以改变Apache的FileEtag设置,比如设置成FileEtag Size,那么得到的Etag可能为:
Etag “5d044840″
总之,设置了几个段,Etag值就有几个段。(不要误以为Etag就是固定的3段式)
说明
这里说的都是Apache 2.2里面的Etag实现,因为HTTP/1.1并没有规定Etag必须是什么样的实现或者格式,因此,你也可以修改或者完全编写自己的算法得到 Etag,比如 “2e681a65d044840″,客户端会记住并缓存下这个Etag(Windows里面保存在哪里,我还没找到:(), 下次访问的时候直接拿这个值去和服务器生成的Etag对比。
注意
不管怎么样的算法,在服务器端都要进行计算,计算就有开销,会带来性能损失。因此为了榨干这一点点性能,不少网站完全把Etag禁用了(比如Yahoo!),这其实不符合HTTP/1.1的规定,因为HTTP/1.1总是鼓励服务器尽可能的开启Etag。
重新考虑前面提到的3个(Last-Modified无法解决的)问题,以apache的etag实现为例:
问题1 、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
解决办法:如果使用强Etag,每次得会要求重新GET页面,如果使用Etag,比方说设置成FileEtag Size等,就可以忽略MTime造成的Last-Modified时间修改从而影响了If-Modified-Since(IMS)这个校验了。这点和弱Etag无关。
问题2、 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
解决办法 :如果是这种情况,Apache会自动判断请求时间和修改时间之间的差值,如果小于1s,Apache 会认为这个文件在这1秒内可能会再次被修改,因此生成一个弱Etag(Weak Etag),这个Etag仅仅基于MTime来生成,因此MTime只能精确到s,所以1s内生成的Etag总是一样,这样就避免了使用强Etag造成的 1s内频繁的刷新Cache的情况。(貌似不用Etag,仅仅使用Last-Modified就可以解决,但是这针对的仅仅是修改超级频繁的情况,很多文件可能同时也使用强Etag验证)。
问题3、 某些服务器不能精确的得到文件的最后修改时间;
解决办法: 生成Etag,因为Etag可以综合Inode,MTime和Size,可以避免这个问题
http://www.path8.net/tn/archives/1765
http://en.wikipedia.org/wiki/HTTP_ETag
分享到:
相关推荐
标题 "Caching HTTP Headers, Last-Modified 和 ETag" 涉及到的是网络缓存中的两个关键概念,它们在优化网站性能、减少服务器负载以及提高用户体验方面扮演着重要角色。HTTP缓存机制允许浏览器存储先前请求过的资源...
在HTTP协议中,Last-Modified和ETag两个头部字段是用来验证缓存是否过期,确保浏览器使用的缓存是最新的。 Last-Modified是一个HTTP头部字段,它包含了服务器上文件的最后修改日期和时间。当浏览器首次请求一个资源...
如果资源的Etag和Last-Modified都能正确匹配,那么客户端就非常确信资源未变,从而有效减少网络带宽的使用和提高加载速度。 4. 缓存控制的优缺点: 优点在于显著提高了性能,降低了服务器负载,提升了用户体验。...
http last-modified字体头
在 MagpieRSS 的 Features 中列举了这样的一条: HTTP Conditional GETs Save bandwidth and speed up download times with intelligent use of Last-Modified and ETag.. 这里的 Etag 引起了我的注意. 什么是 ...
Etag和Last-Modified相结合,可以提供更为精确的缓存验证机制。 总之,Laravel的Etag中间件是提升Web应用性能的一个实用工具,它通过智能缓存策略减少了不必要的数据传输,从而加快了页面加载速度。正确理解和使用...
在Laravel框架中,中间件扮演着至关重要的角色,它们是处理HTTP请求和响应的关键组件。"laravel-weak-etag-middleware"是专为Laravel...在适当的情况下,结合Last-Modified等其他缓存策略,可以达到更优的性能效果。
- **配合Last-Modified**:Etag可以和Last-Modified头一起使用,提供双重验证,提高缓存效率。 - **慎用ETag限速**:在使用Etag进行限速时,要考虑Etag验证的性能影响,以及避免因Etag计算过于频繁导致服务器负担...
或者,可以结合使用Last-Modified和Etag,以提高缓存的有效性和准确性。 总结来说,Etag和Expires是HTTP缓存策略的重要组成部分,它们协同工作,确保客户端能够高效、准确地缓存服务器资源。在实际应用中,开发者...
标题中的“last-modified”通常指的是HTTP响应头中的一个字段,用于指示服务器上资源的最后修改时间。在网页开发中,这个字段可以帮助浏览器判断页面内容是否是最新的,从而决定是否需要重新加载。在这个特定的...
皮克根据 Last-Modified 标头不断检索 Web 资源。 Peeq 基于并因此公开了一个几乎相同的 API,除了它仅在资源已更新时才返回“响应”事件。例子 var Peeq = require ( 'peeq' ) ;var resource = Peeq ( '...
Etags原理:Add an Expires header已经对浏览器缓存机制中的Cache-Control和Expires进行了配置,这一条评测的是另外两个:Last-Modified和ETag。简单的说,即使设置了文件的期限,浏览器在访问资源时也会因为Last-...
Optionsmode 可以是'etag'、'lastModified'、true 、false四种选项 如果是lastModified,则启用Last-Modified机制.如果是false,则不进行304机制检测。默认是 true,使用Etag机制.root 静态资源的根目录, 默认是 ...
使用`Last-Modified`和`ETag`可以显著提升用户体验,减少不必要的网络流量。但需要注意,频繁的文件修改会导致更多的HTTP请求,可能影响服务器性能。因此,合理的文件管理和缓存策略是必要的。 8. **总结** 在ASP...
Etag http If-None-Match If-Modified-Since Last-Modified 使用Demo 已经可以直接使用
修改last-modified的HTTP规范,实现了last-modified , if-modified-since , etag , if-none-match 。概要Modified是根据构建的,并通过缓存支持对其进行修饰,因此,如果您熟悉请求,则几乎可以使用修改了。 var...
离线缓存机制主要依赖于HTTP协议中的缓存策略,包括Last-Modified和ETag等头信息。当UIWebView接收到一个网页请求时,它会检查本地是否有该页面的缓存副本。如果有,且服务器返回的缓存策略允许使用缓存,则...
协商缓存的字段有 Last-Modified / If-Modified-Since 和 Etag / If-None-Match,其中 Etag / If-None-Match 的优先级比 Last-Modified / If-Modified-Since 高。 Last-Modified 字段,它的值是该资源文件在服务器...
4. **回调和Promise支持**:为了适应不同的异步处理模式,last-one-wins可能支持回调函数和Promise接口,让开发者能够选择最适合他们应用场景的方式。 5. **错误处理**:当注册的异步函数抛出错误时,库可能会提供...