您可以请求 http 标头通过查看其日期来检查网页是否已被编辑,但是动态页面(如 php、aspx)如何从数据库中获取其数据?
5 回答
尽管您可能认为它已经过时,但我一直发现 Simon Willison 关于条件 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(我认为其他动词也可以,但我看不出使用它们的原因)。您需要做的就是添加If-Modified-Since
或If-None-Match
使用相应的标题值Last-Modified
或ETag
由页面的先前版本发送。从 HTTP 版本 1.1 开始,建议使用ETag
over Last-Modified
,但两者都可以。
这是条件 GET 如何工作的一个非常简单的示例。首先,我们需要以通常的方式检索页面:
获取 /some-page.html HTTP/1.1 主机:example.org
带有条件标题和内容的第一个响应:
200 好 ETag:您的ETagHere
现在有条件的获取请求:
获取 /some-page.html HTTP/1.1 主机:example.org If-None-Match: YourETagHere
并且响应表明您可以使用页面的缓存版本,因为只有标题将被传递:
304 未修改 ETag:您的ETagHere
有了这个,服务器通知您页面没有修改。
我还可以向您推荐另一篇关于条件 GET 的文章:面向 RSS 黑客的 HTTP 条件 GET。
这是ETag标头的确切用途,但它必须由您的 Web 框架支持,或者您需要注意您的应用程序正确响应带有标头If-Match、If-Not-Match和If-Range的请求(请参阅HTTP 第 3.11 章)。
是的,您可以并且应该使用 HTTP 标头将页面标记为未过期。如果它们是动态的(PHP、ASPX 等)和/或数据库驱动,您需要手动控制设置 Expires 标头/适当地发送未修改的 HTTP。ASP.NET 对此有一些 SqlDependency 对象,但它们仍然需要配置和管理。(不确定 PHP 是否有类似的东西,但如果没有的话,PEAR 中可能有一些东西......)
Last-Modified
仅当站点的程序员明确将其设置为返回时,该标头才对您有用。
对于常规的静态页面Last-Modified
,是 HTML 文件最后一次修改的时间戳。对于动态生成的页面,服务器无法可靠地分配Last-Modified
值,因为它无法真正了解内容如何根据请求发生变化,因此许多服务器根本不生成标头。
如果您可以控制页面,那么确保设置了 Last Modified 标题将确保检查Last-Modified
成功。否则,您可能必须获取页面并执行正则表达式以查找更改的部分(例如,新闻站点标题中的日期/时间)。如果不存在这样明显的标记,那么我会支持 Oli在页面内容上使用 MD5 的建议,以确保它已更改。
如果它正确使用 http 响应标头,则可以,但它经常被忽略。
否则,存储内容的本地 md5 哈希可能对您有用(除非您可以挂出更简单的内容字符串)。这并不理想(因为这是一个相当缓慢的过程),但它是一种选择。