Last-Modified,Etag,Expire区别

时间:2022-10-15 04:34:55

Last-Modified 是什么

Last-Modified 是 HttpHeader 中的资源的最后修改时间,如果带有 Last-Modified ,下一次发送 Http 请求时,将会发生带 If-modified-since 的 HttpHeader 。如果没有过期,将会收到 304 的响应,从缓存中读取。

Etag 是什么

Etag 是 HttpHeader 中代表资源的标签,在服务器端生成。如果带有 Etag ,下一次发送带 Etag 的请求,如果 Etag 没有变化将收到 304 的响应,从缓存中读取。

Etag 在使用时要注意相同资源多台 Web 服务器的 Etag 的一致性。

Expire 是什么

Expire 是 HttpHeader 中代表资源的过期时间,由服务器段设置。如果带有 Expire ,则在 Expire 过期前不会发生 Http 请求,直接从缓存中读取。用户强制 F5 例外。

Last-Modified,Etag,Expire 混合

通常 Last-Modified,Etag,Expire 是一起混合使用的,特别是 Last-Modified 和 Expire 经常一起使用,因为 Expire 可以让浏览器完全不发起 Http 请求,而当浏览器强制 F5 的时候又有 Last-Modified ,这样就很好的达到了浏览器段缓存的效果。

Etag 和 Expire 一起使用时,先判断 Expire ,如果已经过期,再发起 Http 请求,如果 Etag 也过期,则返回 200 响应。如果 Etag 没有过期则返回 304 响应。

Last-Modified,Etag,Expires 三个同时使用时。先判断 Expire ,然后发送 Http 请求,服务器先判断 last-modified ,再判断 Etag ,必须都没有过期,才能返回 304 响应。

第一次访问 200
鼠标点击二次访问 (Cache)
按F5刷新 304
按Ctrl+F5强制刷新 200

为什么要去掉ETag?

使用YSlow对网页进行优化的时候,给的一个建议是Configure Entity Tags(ETag)。这个纠结了好久,最后终于搞明白了。Yahoo网站上面的解释是这样的:

Configure ETags

tag: server

Entity tags (ETags) are a mechanism that web servers and browsers use to determine whether the component in the browser's cache matches the one on the origin server. (An "entity" is another word a "component": images, scripts, stylesheets, etc.) ETags were added to provide a mechanism for validating entities that is more flexible than the last-modified date. An ETag is a string that uniquely identifies a specific version of a component. The only format constraints are that the string be quoted. The origin server specifies the component's ETag using the ETag response header.

      HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195

Later, if the browser has to validate a component, it uses the If-None-Match
header to pass the ETag back to the origin server. If the ETags match, a
304 status code is returned reducing the response by 12195 bytes for
this example.

      GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
If-None-Match: "10c24bc-4ab-457e1c1f"
HTTP/1.1 304 Not Modified

The problem with ETags is that they typically are constructed using
attributes that make them unique to a specific server hosting a site.
ETags won't match when a browser gets the original component from one
server and later tries to validate that component on a different server,
a situation that is all too common on Web sites that use a cluster of
servers to handle requests. By default, both Apache and IIS embed data
in the ETag that dramatically reduces the odds of the validity test
succeeding on web sites with multiple servers.

The ETag format for Apache 1.3 and 2.x is inode-size-timestamp.
Although a given file may reside in the same directory across multiple
servers, and have the same file size, permissions, timestamp, etc., its
inode is different from one server to the next.

IIS 5.0 and 6.0 have a similar issue with ETags. The format for ETags on IIS is Filetimestamp:ChangeNumber. A ChangeNumber is a counter used to track configuration changes to IIS. It's unlikely that the ChangeNumber is the same across all IIS servers behind a web site.

The end result is ETags generated by Apache and IIS for the exact
same component won't match from one server to another. If the ETags
don't match, the user doesn't receive the small, fast 304 response that
ETags were designed for; instead, they'll get a normal 200 response
along with all the data for the component. If you host your web site on
just one server, this isn't a problem. But if you have multiple servers
hosting your web site, and you're using Apache or IIS with the default
ETag configuration, your users are getting slower pages, your servers
have a higher load, you're consuming greater bandwidth, and proxies
aren't caching your content efficiently. Even if your components have a
far future Expires header, a conditional GET request is still made whenever the user hits Reload or Refresh.

If you're not taking advantage of the flexible validation model
that ETags provide, it's better to just remove the ETag altogether. The Last-Modified
header validates based on the component's timestamp. And removing the
ETag reduces the size of the HTTP headers in both the response and
subsequent requests. This Microsoft Support article describes how to remove ETags. In Apache, this is done by simply adding the following line to your Apache configuration file:

      FileETag none

大概思想就是在集群服务器上面,因为ETag的值会很服务器有关,那么对于同样的文件,可能下次请求的时候是发给不同的服务器,结果也会重新发送数据,所以就会影响网页加载速度,增加服务器的压力。一般情况下就要把Etag给去掉,只是用Last_modified和Expire。

如何去掉ETag?

在Apache里面去掉很简单,但是IIS里面去掉就有点棘手,网上有IIS各个的解决方法。我的版本是IIS 8, 使用URL Rewrite解决了,解决方案如下:

If you prefer to not send the ETag HTTP header for files served from IIS 7 or 7.5, it is a bit problematic. To the best of my knowledge, IIS does not provide a straight forward way to remove this header. This post shows a way to do it using Microsoft's URL Rewrite Module 2.0.

I'm not going to go into the what and why of the ETag. Suffice it to say, many web developers and web masters would prefer not to send it.

The ETag can be removed using an outbound URL rewrite rule. You can read more about it at the URL Rewrite Module 2.0 Configuration Reference.

The rewrite rule that can be put in your web.config follows:

<rewrite>
   <outboundRules>
      <rule name="Remove ETag" >
         <match serverVariable="RESPONSE_ETag" pattern=".+" />
         <action type="Rewrite" value="" />
      </rule>
   </outboundRules>
</rewrite>

This graphic shows the settings for the ETag removal rewrite rule in IIS Manager. In fact, if you look at the headers for the image, you'll see there is no ETag :-)

Last-Modified,Etag,Expire区别

If you happen to be using Helicon's Ape, then this is very simple as well. You can use a mod_headers rule like:

Header set ETag ""

I hope this helps :-)

 

什么时候使用ETag?

Etag 主要为了解决 Last-Modified 无法解决的一些问题。
1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
3、某些服务器不能精确的得到文件的最后修改时间
注意:不管怎么样的算法,在服务器端都要进行计算,计算就有开销,会带来性能损失。因此为了榨干这一点点性能,不少网站完全把Etag禁用了(比如Yahoo!),这其实不符合HTTP/1.1的规定,因为HTTP/1.1总是鼓励服务器尽可能的开启Etag