使用PHP如何准确测试远程网站是否支持 "If-Modified-Since"HTTP标头.
根据我的阅读,如果您自GET的远程文件自标题请求中指定的日期以来已被修改 - 它应返回200 OK状态.如果尚未修改,则应返回304 Not Modified.
因此我的问题是,如果服务器不支持"If-Modified-Since"但仍然返回200 OK怎么办?
有一些工具可以检查您的网站是否支持"If-Modified-Since",所以我想我问他们是如何工作的.
编辑:
我使用Curl进行了一些测试,发送以下内容;
curl_setopt($ch, CURLOPT_HTTPHEADER, array("If-Modified-Since: ".gmdate('D, d M Y H:i:s \G\M\T',time()+60*60*60*60))); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_AUTOREFERER, true); curl_setopt($ch, CURLOPT_FORBID_REUSE, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); curl_setopt($ch, CURLOPT_TIMEOUT, 4);
即将来google.com返回的日期;
HTTP/1.0 304 Not Modified Date: Fri, 05 Feb 2010 16:11:54 GMT Server: gws X-XSS-Protection: 0 X-Cache: MISS from . Via: 1.0 .:80 (squid) Connection: close
如果我发送;
curl_setopt($ch, CURLOPT_HTTPHEADER, array("If-Modified-Since: ".gmdate('D, d M Y H:i:s \G\M\T',time()-60*60*60*60))); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_AUTOREFERER, true); curl_setopt($ch, CURLOPT_FORBID_REUSE, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); curl_setopt($ch, CURLOPT_TIMEOUT, 4);
即过去的日期,google.com返回;
HTTP/1.0 200 OK Date: Fri, 05 Feb 2010 16:09:12 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=ISO-8859-1 Server: gws X-XSS-Protection: 0 X-Cache: MISS from . Via: 1.0 .:80 (squid) Connection: close
如果我然后发送到bbc.co.uk(不支持它);
未来的回归;
HTTP/1.1 200 OK Date: Fri, 05 Feb 2010 16:12:51 GMT Server: Apache Set-Cookie: BBC-UID=84bb66bc648318e367bdca3ad1d48cf627005b54f090f211a2182074b4ed92c40ForbSoft%20Web%20Diagnostics%20%28URL%20Validator%29; expires=Tue, 04-Feb-14 16:12:51 GMT; path=/; domain=bbc.co.uk; Accept-Ranges: bytes Cache-Control: max-age=0 Expires: Fri, 05 Feb 2010 16:12:51 GMT Pragma: no-cache Content-Length: 111677 Content-Type: text/html
过去的日期返回;
HTTP/1.1 200 OK Date: Fri, 05 Feb 2010 16:14:01 GMT Server: Apache Set-Cookie: BBC-UID=841b66ec44232cd91e81e88a014a3c5e50ed4e20c0e07174c4ff59675cd2fa210ForbSoft%20Web%20Diagnostics%20%28URL%20Validator%29; expires=Tue, 04-Feb-14 16:14:01 GMT; path=/; domain=bbc.co.uk; Accept-Ranges: bytes Cache-Control: max-age=0 Expires: Fri, 05 Feb 2010 16:14:01 GMT Pragma: no-cache Content-Length: 111672 Content-Type: text/html
所以我的问题仍然存在.
我已经对此进行了一些测试,它似乎工作如下;
如果您发送的If-Modified-Since标头的日期是过去的日期(当前时间之前的5分钟应该这样做),那么google.com,w3.org,mattcutts.com等网站将返回"HTTP" /1.1 304未修改"标题.yahoo.com,bbc.co.uk和stackoverflow.com等网站总是返回"HTTP/1.1 200 OK".
"Last-Modified"标题与"If-Modified-Since" 无关,因为发送回"HTTP/1.1 304 Not Modified"标题的重点是您不必向其发送正文(从而节省带宽 - 这是这背后的重点.
因此,我的问题的答案是,如果站点在您发送"If-Modified-Since 5分钟前"标题时未返回"HTTP/1.1 304 Not Modified"标题,则该站点不支持" If-Modified-自"请求正确.
如果我不正确,请说出来并提供测试以显示.
编辑:我忘了添加一个好的测试是向域发出正常的HEAD请求(例如w3.org),获取"Last Modified"日期,然后使用"If-Modified-Since:"发出另一个请求.这将测试是否支持"Last Modified"值和"If-Modified-Since"请求.请注意:仅仅因为服务器发回"上次修改"日期并不意味着它支持"If-Modified-Since"
如果实体返回"Last-Modified"标头,则它支持它.真有意义.
更多信息:http://httpd.apache.org/docs/2.2/caching.html(有条件请求简要说明)
显然,只有静态页面/文件才会有该标题.对于动态内容(asp,php等),没有办法通过标题知道(除非网站处理程序手动缓存,例如像这样),并且实体可能支持也可能不支持If-Modified-Since,根据我的经验.
也许你可以只做两个请求,一个跟着另一个请求,发送一个If-Modified-Since标头,然后验证第二个请求是304还是200.
编辑 - hurikhan77指出了一个重要的注意事项,例如,测试网站的根目录以获得此功能,并不能保证网站的其他部分也支持这一功能.