【发布时间】:2015-01-26 10:18:26
【问题描述】:
我的网站上有一个代理脚本,用于缩小图像(也将它们保存在本地缓存文件夹中)并将它们与 Etag、缓存标头等一起发送给用户。
但是,当您访问该页面时,您可以清楚地看到图像加载缓慢,即使您关闭选项卡并再次进入该页面 - 显然它们应该在缓存中(或者也许我的连接很糟糕,但我看到它们甚至重新加载在 64 MB/s 连接上)
你可以在这里看到图片,标题照片:http://www.ondrovo.com/
我怀疑我以某种方式发送了错误的标头,我不太确定。
这是我的图像传递函数(有点缩短):
/** Send file to user */
public static function send($file)
{
// ETAG
$last_modified_time = filemtime($file);
$etag = md5_file($file);
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
header("Etag: $etag");
header('Expires: pageload + 168 hours');
header('Cache-Control: public, max-age=604800, must-revalidate');
// exit if not modified
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time ||
@trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
header("HTTP/1.1 304 Not Modified");
exit;
}
$mimetype = self::getMime($path);
if(in_array($mimetype, ['image/jpeg', 'image/png', 'image/pjpeg'])) {
// it's an image
if(isset($_GET['w']) || isset($_GET['h'])) {
// resize, save to cache folder
// $tmp_fname holds the path to the resized image
$file = $tmp_fname;
}
}
header('Content-Type: ' . $mimetype);
header('Content-Length: ' . filesize($file));
readfile($file);
flush();
exit;
}
另外,这里有一个标头转储,如果有帮助的话
请求
GET /about/header.jpg?h=92&w=92 HTTP/1.1
Host: www.ondrovo.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36
Referer: http://www.ondrovo.com/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: cs,en-US;q=0.8,en;q=0.6
Cookie: PHPSESSID=64e177be06a1b7bb665dd756151d014f
回应
HTTP/1.1 200 OK
Date: Thu, 27 Nov 2014 18:31:57 GMT
Server: Apache
Expires: pageload + 168 hours
Cache-Control: public, max-age=604800, must-revalidate
Last-Modified: Fri, 07 Nov 2014 14:39:09 GMT
ETag: b38a22993d1fb1ee17905067340596e4
Content-Length: 2268
Content-Type: image/jpeg
Via: 1.1 vhost.phx6.nearlyfreespeech.net:3128 (squid/2.7.STABLE7)
如果我的标题没问题的话,有人能帮我检查一下吗?
另外,图像通过 GET 参数获取大小可能是个问题吗?
【问题讨论】:
-
确认 strtotime() 实际上正在正确转换您的标头时间戳。永远不要依赖它做“正确的事”。这很好,但它不是万无一失的,也绝对不是无所不知的。