5

您可以请求 http 标头通过查看其日期来检查网页是否已被编辑,但是动态页面(如 php、aspx)如何从数据库中获取其数据?

4

5 回答 5

2

尽管您可能认为它已经过时,但我一直发现 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 动词GETHEAD(我认为其他动词也可以,但我看不出使用它们的原因)。您需要做的就是添加If-Modified-SinceIf-None-Match使用相应的标题值Last-ModifiedETag由页面的先前版本发送。从 HTTP 版本 1.1 开始,建议使用ETagover 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

于 2008-10-25T13:09:31.543 回答
1

这是ETag标头的确切用途,但它必须由您的 Web 框架支持,或者您需要注意您的应用程序正确响应带有标头If-MatchIf-Not-MatchIf-Range的请求(请参阅HTTP 第 3.11 章)。

于 2008-10-15T14:34:03.693 回答
0

是的,您可以并且应该使用 HTTP 标头将页面标记为未过期。如果它们是动态的(PHP、ASPX 等)和/或数据库驱动,您需要手动控制设置 Expires 标头/适当地发送未修改的 HTTP。ASP.NET 对此有一些 SqlDependency 对象,但它们仍然需要配置和管理。(不确定 PHP 是否有类似的东西,但如果没有的话,PEAR 中可能有一些东西......)

于 2008-10-15T14:32:29.733 回答
0

Last-Modified仅当站点的程序员明确将其设置为返回时,该标头才对您有用。

对于常规的静态页面Last-Modified,是 HTML 文件最后一次修改的时间戳。对于动态生成的页面,服务器无法可靠地分配Last-Modified值,因为它无法真正了解内容如何根据​​请求发生变化,因此许多服务器根本不生成标头。

如果您可以控制页面,那么确保设置了 Last Modified 标题将确保检查Last-Modified成功。否则,您可能必须获取页面并执行正则表达式以查找更改的部分(例如,新闻站点标题中的日期/时间)。如果不存在这样明显的标记,那么我会支持 Oli在页面内容上使用 MD5 的建议,以确保它已更改。

于 2008-10-15T14:40:12.323 回答
0

如果它正确使用 http 响应标头,则可以,但它经常被忽略。

否则,存储内容的本地 md5 哈希可能对您有用(除非您可以挂出更简单的内容字符串)。这并不理想(因为这是一个相当缓慢的过程),但它是一种选择。

于 2008-10-15T14:21:28.693 回答