如何缓存脚本图像

时间:2013-05-18 12:11:41

标签: php caching

我想实现一个脚本,在所请求的文件(图像)上生成缩略图。以下是一个简单的操作列表,用于理解脚本的工作原理:

  • 请求服务器url/preset/filename.jpg
  • 检查文件是否已被翻阅
  • 如果没有,请生成新文件并返回该文件。 如果存在则返回翻阅的文件。

这很完美,但问题是浏览器没有缓存图像。我对缓存并不熟悉。我想通过返回304 Not modified会触发浏览器从缓存中获取图像,但它会挂起处于挂起状态。

有人知道如何缓存这些图片吗?

这是我剧本的节目部分:

private function _show_image($file_path, $filename, $new = FALSE) {
        $this->load->helper('file');

        if($new) { 
            header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
        } else {
            //header('HTTP/1.1 304 Not Modified');
            header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');  
        }

        header('Cache-Control: public'); // needed for i.e.
        header('Content-type: ' . get_mime_by_extension($file_path));
        header('Content-Transfer-Encoding: Binary');
        header('Content-Length:' . filesize($file_path));
        //header('Content-Disposition: attachment; filename=' . $filename);
        header('Content-Disposition: inline; filename=' . $filename);
        readfile($file_path);
        exit(); 
    }

更新

我更新了代码,以便首先检查$_SERVER['HTTP_IF_MODIFIED_SINCE']是否已设置,如果是,则检查所有检查内容。但问题是浏览器没有发送那个标题..

以下是访问文件时的发送和接收标头。

请求

Accept:*/*
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Cookie:PHPSESSID=heiog0hdasg181l45cfbm7u353; __jwpusr=264f6c61-3752-4682-a61b-e02b822c7815
Host:domain.local
Range:bytes=0-
Referer:http://domain.local/test
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36

响应

Cache-Control:public
Connection:Keep-Alive
Content-Description:File Transfer
Content-disposition:inline
Content-Length:24103476
Content-Transfer-Encoding:binary
Content-Type:video/mp4
Date:Thu, 30 May 2013 14:07:02 GMT
Expires:0
Keep-Alive:timeout=5, max=98
Last-Modified:Wed, 29 May 2013 09:03:30 GMT
Server:Apache/2.2.22 (Win32) PHP/5.3.13
X-Frame-Options:SAMEORIGIN
X-Powered-By:PHP/5.3.13
X-XSS-Protection:1; mode=block 

3 个答案:

答案 0 :(得分:2)

如果客户端向您发送了If-Modified-Since标头,您只能发送304“Not Modified”,如:

  

If-Modified-Since:Sat,1994年10月29日19:43:31 GMT

或If-None-Match:

  

If-None-Match:“737060cd8c284d8af7ad3082f209582d”

您无法知道图片是否仍在浏览器的缓存中,或者是否已清除。正确的操作是在创建缩略图时返回图像。如果缩略图存在,请检查If-Modified-Since标头(这是指示其当前在其缓存中具有该文件的浏览器),如果文件未更改,则返回304 Not Modified。否则返回该文件,因为它不在浏览器的缓存中。

If-None-Match系统使用eTags,如果你不需要处理它们,你最好避免使用它们。

答案 1 :(得分:2)

如果您使用的是Apache,那么最好添加mod_rewrite。您可以创建一个重写规则,只有在请求的图像不存在时才将请求重定向到PHP。

缩略图目录中的

.htaccess文件:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /thumbnailer.php

thumbnailer.php然后需要检查$ _SERVER ['REDIRECT_URL'](或一些类似的变量,检查phpinfo)以查看需要生成哪个文件。

答案 2 :(得分:1)

如果可以,我的第一个提示是将缓存留给Apache本身。它最了解如何发送标头并响应缓存请求。

如果你真的想自己做,你需要弄清楚浏览器何时请求图片或只是检查是否有变化(If-Modified-Since)。

您没有设置过期或最大年龄,因此可能根本没有缓存图像。

Expires Mon, 16 Oct 2012 11:07:06 GMT
Cache-Control   public, max-age=120

当它发出新请求(没有If-Modified-Since)时,你刚刚发回了一个它没想到的304。