【问题标题】:How to cache dynamically created images?如何缓存动态创建的图像?
【发布时间】:2017-04-20 16:36:17
【问题描述】:

我有一个生成 *.png 图片但 不 将它们存储在服务器上的 php 脚本。这些图片将重复显示给同一用户。我正在寻找一种方法来缓存这些图片。我可以发送 304 状态标头,浏览器还会在第一次刷新时将网页声明为缓存(因为它在 web-inspector 中可见),但网页显示为空白。在第二次刷新后,甚至 web-inspector 也显示为空白。

谁能帮我看看我哪里搞砸了?

注意事项:

  • 我读过this post,但对我没有帮助。
  • 使用 MAMP(PHP 版本 7.0.10)
  • 我是新手,对于丑陋的代码,我深表歉意。

以下是文件的主要行:

session_start();
header("Content-type: image/jpeg");
//A little require_once() here on some functions stored in an other file.
$originalSource = getSource($_GET['src']);
if (isset($_COOKIE[sha1($originalSource)]) && $_COOKIE[sha1($originalSource)]) {
    header("HTTP/1.1 304 Not Modified");
    die;
} else {
    setcookie (sha1($originalSource), true, time()+10);
    $offset = 10;
    $expire = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
    header($expire);
    header("Cache-Control: max-age=".$offset);
    header("Last-Modified: Wed, 25 Feb 2015 12:00:00 GMT");
}
//The entire image generation process after this

谢谢你的帮助????

【问题讨论】:

    标签: php caching php-gd


    【解决方案1】:

    您的服务器在这里决定它是否认为浏览器仍应缓存图像。显然,这几乎不是权威。浏览器可能不缓存图像的原因有很多,例如如果您打开检查器工具(通常会禁用缓存)。

    浏览器有一种机制可以通知服务器其缓存状态:the HTTP headers If-None-Match 用于ETags 和If-Modified-Since 用于基于时间的到期。如果请求中存在这两个标头中的任何一个,则意味着浏览器仍然拥有缓存的资源副本,并且很乐意接受304 响应,而不是再次下载资源。

    如果您在响应中设置ETag 标头,浏览器将使用If-None-Match 发出另一个请求(这实际上取代了您的cookie 机制,更可靠);如果您只是设置过期日期,浏览器将使用If-Modified-Since 标头再次检查服务器。这就是您的304 回复的基础。

    使用 ETag 的示例:

    $hash = sha1($originalSource);
    
    header("Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT");
    
    if (
        isset($_SERVER['HTTP_IF_NONE_MATCH']) &&
        trim($_SERVER['HTTP_IF_NONE_MATCH'], '"') === $hash
    ) {
        header("HTTP/1.1 304 Not Modified");
        exit;
    }
    
    header("Content-type: image/jpeg");
    header("Cache-Control: max-age=$offset");
    header("ETag: \"$hash\"");
    
    // output image
    

    【讨论】:

    • 谢谢@deceze!所以我的代码现在看起来像this。但它仍然没有缓存。 These 是我得到的标题。 1. 我需要在 MAMP 上启用“APC”或“OPCache”吗? 2. 我需要session_start(); 吗? 3. 有没有可能是Pragma = no-cache 导致了这个问题?很抱歉有很多问题。
    • APC 等与这种缓存无关。是的,Pragma no-cache 在这里似乎适得其反。
    • 另请注意,您的Date 和Expires 是相同的,这意味着它会立即过期。
    • 重新编辑:字符串中带有变量的代码是正确的。
    • 即使我什么都没做也终于可以工作了。我想时间会治愈。感谢您的帮助!
    猜你喜欢
    • 2011-04-01
    • 2013-12-25
    • 2013-09-12
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    相关资源
    最近更新 更多