【发布时间】:2010-09-17 07:42:06
【问题描述】:
您可以通过查看日期来请求 http 标头来检查网页是否已被编辑,但是动态页面(例如 - php、aspx - 从数据库中获取其数据)呢?
【问题讨论】:
-
是否有任何建议的解决方案适合您?
标签: http-headers
您可以通过查看日期来请求 http 标头来检查网页是否已被编辑,但是动态页面(例如 - php、aspx - 从数据库中获取其数据)呢?
【问题讨论】:
标签: http-headers
尽管您可能认为它已经过时,但我一直发现 Simon Willison 在 Conditional GET 上的文章非常有用。该示例是用 PHP 编写的,但它非常简单,您可以将其调整为其他语言。这是一个例子:
function doConditionalGet($timestamp) {
// A PHP implementation of conditional get, see
// http://fishbowl.pastiche.org/archives/001132.html
$last_modified = substr(date('r', $timestamp), 0, -5).'GMT';
$etag = '"'.md5($last_modified).'"';
// Send the headers
header("Last-Modified: $last_modified");
header("ETag: $etag");
// See if the client has provided the required headers
$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
false;
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) :
false;
if (!$if_modified_since && !$if_none_match) {
return;
}
// At least one of the headers is there - check them
if ($if_none_match && $if_none_match != $etag) {
return; // etag is there but doesn't match
}
if ($if_modified_since && $if_modified_since != $last_modified) {
return; // if-modified-since is there but doesn't match
}
// Nothing has changed since their last request - serve a 304 and exit
header('HTTP/1.0 304 Not Modified');
exit;
}
有了这个,您可以使用 HTTP 动词 GET 或 HEAD(我认为 others 也可以,但我看不出使用它们的原因)。您需要做的就是添加If-Modified-Since 或If-None-Match 以及先前版本页面发送的标题Last-Modified 或ETag 的相应值。从 HTTP 版本 1.1 开始,建议使用 ETag 而不是 Last-Modified,但两者都可以。
这是一个非常简单的示例,说明了条件 GET 的工作原理。首先,我们需要以通常的方式检索页面:
GET /some-page.html HTTP/1.1 主机:example.org
带有条件标题和内容的第一个响应:
200 OK ETag:YourETagHere
现在是条件获取请求:
GET /some-page.html HTTP/1.1 主机:example.org If-None-Match: YourETagHere
并且响应表明您可以使用页面的缓存版本,因为只会传递标题:
304 未修改 ETag:YourETagHere
服务器通知您页面没有修改。
我还可以向您推荐另一篇关于条件 GET 的文章:HTTP conditional GET for RSS hackers。
【讨论】:
这是 ETag 标头的确切用途,但它必须由您的 Web 框架支持,或者您需要注意您的应用程序正确响应带有标头的请求 If-Match、If-Not-Match 和 If-Range(参见HTTP Ch 3.11)。
【讨论】:
如果它正确使用 http 响应标头,则可以,但它经常被忽略。
否则,存储内容的本地 md5 哈希可能对您有用(除非您可以挂出更简单的内容字符串)。这并不理想(因为这是一个相当缓慢的过程),但它是一种选择。
【讨论】:
是的,您可以并且应该使用 HTTP 标头将页面标记为未过期。如果它们是动态的(PHP、ASPX 等)和/或数据库驱动,您需要手动控制设置 Expires 标头/适当地发送未修改的 HTTP。 ASP.NET 为此提供了一些 SqlDependency 对象,但它们仍需要配置和管理。 (不确定 PHP 是否有类似的东西,但如果没有的话,PEAR 中可能有一些东西......)
【讨论】:
Last-Modified 标头只有在站点的程序员明确设置为返回时才对您有用。
对于常规的静态页面,Last-Modified 是 HTML 文件最后一次修改的时间戳。对于动态生成的页面,服务器无法可靠地分配 Last-Modified 值,因为它无法真正了解内容如何根据请求发生变化,因此许多服务器根本不生成标头。
如果您可以控制页面,那么确保设置了 Last Modified 标头将确保对 Last-Modified 的检查成功。否则,您可能必须获取页面并执行正则表达式以查找更改的部分(例如,新闻站点标题中的日期/时间)。如果不存在这样明显的标记,那么我会在页面内容上使用 MD5 的第二个 Oli's suggestion,以确保它已更改。
【讨论】: