nginx与apache对于If-Modified-Since实现的不同

By pengyao - Last updated: 星期一, 四月 26, 2010 - Save & Share - 2 Comments

在HTTP 1.1中,If-Modified-Since与Last-Modified互成一对,用来判断浏览器cache是否已经有效,对此,HTTP 1.0 RFC1945对此有如下说明:

The If-Modified-Since request-header field is used with the GET  method to make it conditional: if the requested resource has not been modified since the time specified in this field, a copy of the   resource will not be returned from the server; instead, a 304 (not  modified) response will be returned without any Entity-Body.

无意中测试发现nginx与apache对此有不同的算法:

APACHE:

(1)直接发送请求,返回200,Last-Modified: Mon, 26 Apr 2010 13:22:17 GMT

[root@test ~]# curl -I http://www.pengyao.org/test.html

HTTP/1.1 200 OK
Date: Mon, 26 Apr 2010 14:59:09 GMT
Server: Apache/1.3.41 (Unix)
Last-Modified: Mon, 26 Apr 2010 13:22:17 GMT
ETag: “92c027-897-4bd59389″
Accept-Ranges: bytes
Content-Length: 2199
Content-Type: text/plain
(2)指定与Last-Modified时间相同的If-Modified-Since 发送GET请求,返回304

[root@test ~]# curl -I -G -H “If-Modified-Since: Mon, 26 Apr 2010 13:22:17 GMT”  http://www.pengyao.org/test.html

HTTP/1.1 304 Not Modified
Date: Mon, 26 Apr 2010 15:02:06 GMT
Server: Apache/1.3.41 (Unix)
ETag: “92c027-897-4bd59389″

(3)调后If-Modified-Since 1小时,再次发送GET请求,返回依然为304
[root@test ~]# curl -I -G -H “If-Modified-Since: Mon, 26 Apr 2010 14:22:17 GMT”  http://www.pengyao.org/test.html

HTTP/1.1 304 Not Modified
Date: Mon, 26 Apr 2010 15:05:02 GMT
Server: Apache/1.3.41 (Unix)
ETag: “92c027-897-4bd59389″

说明Apache 在判断浏览器cache是否过期时,依据从If-Modified-Since开始,文件Last-Modified是否修改过来判断的,与RFC1945中对If-Modified-Since描述吻合.

那么再看下nginx对于此的测试结果:

(1)直接发送请求,返回200,Last-Modified: Wed, 21 Apr 2010 13:14:21 GMT
[root@test pengyao.org]# curl -I http://www.pengyao.org/index.html
HTTP/1.1 200 OK
Server: nginx/0.7.61
Date: Mon, 26 Apr 2010 15:18:29 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 323
Last-Modified: Wed, 21 Apr 2010 13:14:21 GMT
Connection: keep-alive
Accept-Ranges: bytes

(2)指定与Last-Modified时间相同的If-Modified-Since 发送GET请求,返回304

[root@test pengyao.org]# curl -I -G -H “If-Modified-Since: Wed, 21 Apr 2010 13:14:21 GMT” http://www.pengyao.org/index.html
HTTP/1.1 304 Not Modified
Server: nginx/0.7.61
Date: Mon, 26 Apr 2010 15:20:45 GMT
Last-Modified: Wed, 21 Apr 2010 13:14:21 GMT
Connection: keep-alive

(3)调后If-Modified-Since 1小时,再次发送GET请求,发现返回的结果为200,与Apache不同

[root@test pengyao.org]# curl -I -G -H “If-Modified-Since: Wed, 21 Apr 2010 14:14:21 GMT” http://www.pengyao.org/index.html
HTTP/1.1 200 OK
Server: nginx/0.7.61
Date: Mon, 26 Apr 2010 15:21:19 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 323
Last-Modified: Wed, 21 Apr 2010 13:14:21 GMT
Connection: keep-alive
Accept-Ranges: bytes
由此可以判断出,nginx在判断浏览器cache是否过期时,判断If-Modified-Since与Last-Modified是否匹配,如果不匹配,则认为cache过期,返回200重新下载.

要说更喜欢哪种算法,个人更倾向于nginx的这种,因为在对文件更新前,本人习惯于对需要修改的文件进行备份(保留时间戳),一旦测试出现问题,及时的回滚,使用nginx的这种算法就能保障回滚前后浏览器cache失效,而Apache的这种策略导致回滚到之前的时间戳的话(Last-Modified),本地由于进行了测试,本地cache文件的If-Modified-Since时间一般比回滚后的Last-Modified新,这样本地的cache认为依然有效,返回304,而实际上文件已经不是最新的。当然,Apache的这样设计完全遵守RFC,个人喜好不代表真实需求.

如果你想对If-Modified-Since了解更多,可以直接访问RFC 1945:http://www.w3.org/Protocols/rfc1945/rfc1945

Posted in Gnu/linux • Tags: , , , Top Of Page

2 Responses to “nginx与apache对于If-Modified-Since实现的不同”

Comment from 匿名
Time 2010年08月21日 at 23:15

if_modified_since before;

Comment from pengyao
Time 2010年08月22日 at 17:20

呵呵,前两天查询nginx的手册,确实是

Write a comment