图像代理缓存问题 - 标题错误?

时间:2014-11-27 18:36:18

标签: php http caching

我的网站上有一个代理脚本,可以缩小图像(也将它们保存在本地缓存文件夹中),并将它们与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参数获得尺寸可能是个问题吗?

1 个答案:

答案 0 :(得分:0)

首先,标题Expires: pageload + 168 hours不符合正确的语法。它应该是一个时间戳。

  

5.3。到期

     

"到期"标题字段给出日期/时间之后的
  回应被认为是陈旧的。有关详细讨论,请参见第4.2节   新鲜模型。

     

Expires字段的存在并不意味着原来的   资源将在该日期之前,之前或之后发生变化或停止存在   时间。

     

Expires值是一个HTTP日期时间戳,如Section中所定义      [RFC7231]的7.1.1.1。

 Expires = HTTP-date
     

例如

 Expires: Thu, 01 Dec 1994 16:00:00 GMT
     

缓存收件人必须解释无效的日期格式,尤其是   值" 0",表示过去的时间(即"已经是
  过期"。)

rfc 7234, section 5.3

但是,Cache-Control标题应该覆盖客户端。

您使用哪个客户进行跟踪?看起来显然要求重新加载整个页面,两者都来自

  

Pragma:no-cache   缓存控制:无缓存   (要求squid服务器不提供缓存内容)

缺少标题会暗示客户端已经缓存了资源(If-None-Match,If-Modified-Since)。

请注意,如果以私密/隐身模式访问网站,则根据功能的实施情况,浏览器可能无法缓存任何资源。