我在 PHP 中实现的 HTTP 条件获取答案是否可以?

Is my implementation of HTTP Conditional Get answers in PHP is OK?(我在 PHP 中实现的 HTTP 条件获取答案是否可以?)
本文介绍了我在 PHP 中实现的 HTTP 条件获取答案是否可以?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

经过大量搜索、阅读我找到的每个教程并在这里提出一些问题后,我终于设法正确地(至少我认为)回答了 if-none-match 和 if-modified-since HTTP 请求.

After searching a lot, reading every tutorials I've found and asking some questions here, I've finally managed to answer corrctly (at least I think) to if-none-match and if-modified-since HTTP requests.

快速回顾一下,这就是我在每个可缓存页面上所做的:

To do a quick recap, this is what I do on every pages cacheable:

session_cache_limiter('public'); //Cache on clients and proxies
session_cache_expire(180); //3 hours
header('Content-Type: ' . $documentMimeType . '; charset=' . $charset);
header('ETag: "' . $eTag . '"'); //$eTag is a MD5 of $currentLanguage + $lastModified
if ($isXML)
    header('Vary: Accept'); //$documentMimeType can be either application/xhtml+xml or text/html for XHTML (based on $_SERVER['HTTP_ACCEPT'])
header('Last-Modified: ' . $lastModified);
header('Content-Language: ' . $currentLanguage);

此外,每个页面都有自己的 URL(对于每种语言).例如,index.php"将在英文网址/en/home"和法文网址/fr/accueil"下提供.

Also, every page have it's own URL (for every languages). For example, "index.php" will be served under URL "/en/home" in English and "/fr/accueil" in French.

我的大问题是仅在需要时对 if-none-match 和 if-modified-since HTTP 请求响应304 Not Modified".

My big problem was to answer a "304 Not Modified" to if-none-match and if-modified-since HTTP requests only when needed.

我找到的最好的文档是:http://rithiur.anthd.com/tutorials/conditionalget.php

The best doc I've found is: http://rithiur.anthd.com/tutorials/conditionalget.php

这是我做的实现(这段代码在可以缓存的页面上称为ASAP):

And this is the implementation I did of it (this piece of code is called ASAP on pages that can be cached):

$ifNoneMatch = array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) ? $_SERVER['HTTP_IF_NONE_MATCH'] : false;
$ifModifiedSince = array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;

if ($ifNoneMatch !== false && $ifModifiedSince !== false)
{
    //Both if-none-match and if-modified-since were received.
    //They must match the document values in order to send a HTTP 304 answer.
    if ($ifNoneMatch == $eTag && $ifModifiedSince == $lastModified)
    {
        header('Not Modified', true, 304);
        exit();
    }
}
else
{
    //Only one header received, it it match the document value, send a HTTP 304 answer.
    if (($ifNoneMatch !== false && $ifNoneMatch == $eTag) || ($ifModifiedSince !== false && $ifModifiedSince == $lastModified))
    {
        header('Not Modified', true, 304);
        exit();
    }
}

我的问题有两个:

  • 这是正确的做法吗?我的意思是,当发送 if-none-match 和 if-modified-since 时,both 必须匹配才能回答 304,如果只发送两者之一,则只匹配这个就可以发送304?
  • 在此处描述的上下文中使用时,这 2 个代码段是否对公共缓存友好(我的意思是在代理网络浏览器上对缓存友好)?
  • Is it the correct way to do it? I mean when if-none-match and if-modified-since are sent, both must match to answer a 304, and if only one of the two is sent, only matching this one is OK to send a 304?
  • When used in the context described here, is these 2 snippets are public cache friendly (I mean cache friendly on proxies and Web browsers)?

顺便说一句,我只使用 PHP 5.1.0+(我不支持低于它的版本).

BTW, I use PHP 5.1.0+ only (I don't support versions lower that that).

增加了赏金……我期待高质量的回答.如果您在猜测某事,请不要回答/投票!

Added bounty... I expect quality answer. Don't answer/vote if you are guessing something!

推荐答案

  • 这不太正确.请看一下算法:alt text http://img532.imageshack.us/img532/1017/cache.png
  • 该解决方案是代理友好的,您可以使用 Cache-control: proxy-revalidate 强制缓存遵守您提供的有关资源的任何新鲜信息(仅适用于共享|代理缓存)
  • 以下是可能有用的函数:

    Here is the function that might help:

    function isModified($mtime, $etag) {
        return !( (
            isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])
            && 
            strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $mtime
        ) || (
            isset($_SERVER['HTTP_IF_NONE_MATCH'])
            && 
            $_SERVER['HTTP_IF_NONE_MATCH'] == $etag
        ) ) ;
    }
    

    我建议你看看下面的文章:http://www.peej.co.uk/articles/http-caching.html

    I suggest that you take a look at the following article: http://www.peej.co.uk/articles/http-caching.html

    更新:

    [AlexV] 甚至可以同时接收 if-none-match 和 if-modified-since 吗?

    [AlexV] Is is even possible to receive if-none-match AND if-modified-since at the same time?

    你绝对可以同时设置.然而:

    You can definitely have both set. However:

    如果没有实体标签匹配,那么服务器可以执行请求的方法,就好像 If-None-Match 头字段不存在一样,但也必须忽略任何 If-Modified-Since 头字段中的要求.也就是说,如果没有实体标签匹配,则服务器不得返回 304(未修改)响应.

    If none of the entity tags match, then the server MAY perform the requested method as if the If-None-Match header field did not exist, but MUST also ignore any If-Modified-Since header field(s) in the request. That is, if no entity tags match, then the server MUST NOT return a 304 (Not Modified) response.

    RFC2616 #14.26

    示例值(W 代表弱";阅读更多内容RFC2616 #13.3.3):

    Example values (W stands for 'weak'; read more in RFC2616 #13.3.3):

    If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
    If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
    If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
    If-None-Match: *
    

    作为一种特殊情况,值*"匹配资源的任何当前实体.

    As a special case, the value "*" matches any current entity of the resource.

    这篇关于我在 PHP 中实现的 HTTP 条件获取答案是否可以?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

    本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

DeepL的翻译效果还是很强大的,如果我们要用php实现DeepL翻译调用,该怎么办呢?以下是代码示例,希望能够帮到需要的朋友。 在这里需要注意,这个DeepL的账户和api申请比较难,不支持中国大陆申请,需要拥有香港或者海外信用卡才行,没账号的话,目前某宝可以
PHP通过phpspreadsheet导入Excel日期,导入系统后,全部变为了4开头的几位数字,这是为什么呢?原因很简单,将Excel的时间设置问文本,我们就能看到该日期本来的数值,上图对应的数值为: 要怎么解决呢?进行数据转换就行,这里可以封装方法,或者用第三方的
mediatemple - can#39;t send email using codeigniter(mediatemple - 无法使用 codeigniter 发送电子邮件)
Laravel Gmail Configuration Error(Laravel Gmail 配置错误)
Problem with using PHPMailer for SMTP(将 PHPMailer 用于 SMTP 的问题)
Issue on how to setup SMTP using PHPMailer in GoDaddy server(关于如何在 GoDaddy 服务器中使用 PHPMailer 设置 SMTP 的问题)