douzhang8033 2016-10-31 10:30
浏览 21
已采纳

如何缓存动态创建的图像?

I have a php script that generates *.png pictures but does not store them on the server. Those pictures will be shown to a same user repeatedly. I'm looking for a way to cache those pictures. I'm able to send the 304 status header, the browser also declares the webpage as cached at first refresh (as it is visible in the web-inspector) but the webpage is shown blank. After a second refresh even the web-inspector shows blank.

Can someone help me and tell where I messed up?

Notes:

  • I've read this post but it didn't help me.
  • Using MAMP (PHP version 7.0.10)
  • I'm a newbie, my apologies for the ugly code.

Here are the main lines of the file:

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

Thanks for your help

  • 写回答

1条回答 默认 最新

  • dpprx26000 2016-10-31 10:52
    关注

    Your server is the one deciding here whether it thinks the browser should still have the image cached or not. Obviously it is hardly the authority on that. There are any number of reasons why the browser may not have the image cached, e.g. if you open the inspector tools (which typically disables caching).

    The browser has a mechanism for informing the server about its cache status: the HTTP headers If-None-Match for ETags and If-Modified-Since for time-based expiry. If any of these two headers is present in the request, that means the browser still has a copy of the resourced cached and would happily accept a 304 response instead of downloading the resource again.

    If you set an ETag header in your response, the browser will do another request using If-None-Match (that essentially replaces your cookie mechanism, more reliably); if you just set an expiration date, the browser will check again with the server using the If-Modified-Since header. That's what you should base your 304 reply on.

    Example using ETags:

    $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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据