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

How to cache dynamically created images?

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

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

备注:

文件的主要内容如下:

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

感谢您的帮助

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

浏览器有一种机制可以通知服务器其缓存状态:the HTTP headers If-None-Match for ETagsIf-Modified-Since time-based 过期。如果这两个 header 中的任何一个出现在请求中,这意味着浏览器仍然缓存了资源的副本,并且会很乐意接受 304 响应而不是再次下载资源。

如果您在响应中设置 ETag header,浏览器将使用 If-None-Match 执行另一个请求(这实质上取代了您的 cookie 机制,更可靠);如果你只是设置一个过期日期,浏览器将使用 If-Modified-Since header 与服务器再次检查。这就是您 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