我使用简单的PHP代码(zend框架)来动态调整jpg图像。
问题是我总是以HTTP 200状态结束,而不是304并允许浏览器缓存图像。
我无法获取apache标头,function_exists('apache_request_headers')
为false,而在服务器变量中我只有
'HTTP_ACCEPT' => 'image/png,image/*;q=0.8,*/*;q=0.5',
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'HTTP_ACCEPT_ENCODING' => 'gzip,deflate',
'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
'HTTP_CACHE_CONTROL' => 'max-age=0',
'HTTP_CONNECTION' => 'keep-alive',
'HTTP_COOKIE' => '***',
'HTTP_HOST' => 'automobi.li',
'HTTP_KEEP_ALIVE' => '300',
'HTTP_REFERER' => 'http://automobi.li/oglas/Opel+Astra/2',
'HTTP_USER_AGENT' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 FirePHP/0.4',
我正在发送
$lastModified = filemtime($path);
$etag = md5_file($path);
$this->getResponse()->setHeader('Content-type', 'image/jpeg');
$this->getResponse()->setHeader('Cache-Control', 'public');
$this->getResponse()->setHeader('Last-Modified', gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
$this->getResponse()->setHeader('Cache-Control', 'max-age=86400, must-revalidate');
$this->getResponse()->setHeader('Expires', gmdate('D, d M Y H:i:s', time() + 86400 ) . ' GMT');
$this->getResponse()->setHeader('ETag', $etag);
我希望服务器变量中的HTTP_IF_MODIFIED_SINCE或类似物,所以我可以这样做
if ($this->getRequest()->getHeader('IF_MODIFIED_SINCE') == $lastModified) {
$this->getResponse()->setHttpResponseCode(304);
} else {
$w = (int) $this->_getParam('w');
$h = (int) $this->_getParam('h');
$image->resize($path, $w, $h);
}
有什么想法吗?
答案 0 :(得分:0)
Last-Modified 和 If-Modified-Since 值不进行相等性比较。它们都代表着时代。如果 Last-Modified 时间大于 If-Modified-Since 时间(因此上次修改需要花费时间 If-Modified-Since ),条件满足,304应该发送。
因此,您需要解析 If-Modified-Since 值(尝试strtotime
)并比较 Last-Modified 时间大于的值 If-Modified-Since 时间:
if ($lastModified > strtotime($this->getRequest()->getHeader('IF_MODIFIED_SINCE'))) {
$this->getResponse()->setHttpResponseCode(304);
}
答案 1 :(得分:0)
已修复
$this->getResponse()->setHeader('Content-type', 'image/jpeg');
$this->getResponse()->setHeader('Expires', '', true);
$this->getResponse()->setHeader('Cache-Control', 'public', true);
$this->getResponse()->setHeader('Cache-Control', 'max-age=3800');
$this->getResponse()->setHeader('Pragma', '', true);
$this->getResponse()->setHeader('ETag', $etag);
if ($etag == $this->getRequest()->getHeader('If-None-Match')) {
$this->getResponse()->setHttpResponseCode(304);
} else {
$w = (int) $this->_getParam('w');
$h = (int) $this->_getParam('h');
$image->resize($path, $w, $h);
}
感谢http://dustint.com/archives/25
当我添加
$this->getResponse()->setHeader('Expires', '', true);
$this->getResponse()->setHeader('Cache-Control', 'public', true);
$this->getResponse()->setHeader('Cache-Control', 'max-age=3800');
$this->getResponse()->setHeader('Pragma', '', true);
请求中出现If-None-Match标头,这有助于我将其与etag匹配。
@Gumbo哦,我明白了:)
感谢所有试图提供帮助的人。
答案 2 :(得分:0)
这段代码片段可能有所帮助,它总是对我有用,试图将缓存控制集成到Zend Framework中动态生成的图像中:
if ($mod_since = $this->getRequest()->getHeader('If-Modified-Since')) {
$request_modified = explode(';', $mod_since);
$request_modified = strtotime($request_modified[ 0 ]);
}
if ($this->getFiletime($path, $filename) > 0 && $this->getFiletime($path, $filename) <= $request_modified) {
// Image has not changed since last call, force Browser to reload from cache.
header('HTTP/1.1 304 Not Modified');
exit();
} else {
// Image has changed or browser has no cache
$mimetype = $this->getMIMEType($path, $filename);
$format = substr(strstr($mimetype, "/"), 1);
$this->getResponse()->setHeader('Content-type', $mimetype);
$expires = 60 * 60 * 24 * 3;
$exp_gmt = gmdate("D, d M Y H:i:s", time() + $expires) . " GMT";
$mod_gmt = gmdate("D, d M Y H:i:s", $this->getFiletime($path, $filename)) . " GMT";
$imagedata = $this->_processor->processImage($path, $filename, $w, $h, $crop, $format);
// Send Headers for Browser Caching Control
$this->getResponse()->setHeader('Expires', $exp_gmt, true);
$this->getResponse()->setHeader('Last-Modified', $mod_gmt, true);
$this->getResponse()->setHeader('Cache-Control', 'public, max-age=' . $expires, true);
$this->getResponse()->setHeader('Pragma', '!invalid', true);
$this->getResponse()->setHeader('Content-Length', strlen($imagedata), true);
$this->getResponse()->setHeader('ETag', md5($imagedata), true);
// Save image in Zend Framework's server side Cache or get it from there
$cache_id = str_replace(".", '', $path . "_" . $filename . "_" . $w . "_" . $h . "_" . $crop . "_" . $format);
if (!$result = $this->_cache->load($cache_id)) {
$result = $imagedata;
$this->_cache->save($result, $cache_id, array('image', $path . '_' . str_replace(".", '', $filename)));
}
echo $result;
}