2012-03-23 66 views
1

我使用的是Apache,当我第一次直接请求图像时,图像的状态为“200 OK”。后续请求的状态为“304未修改”,这很好,因为它为客户端和服务器都节省了带宽。PHP:在Webroot和缓存之外流式传输图像

我正在开发一个可以让用户上传图片的网站。这些图像需要存储在webroot之外,不仅可以防止盗链,还可以收集图像统计信息。所以我的想法是使用PHP脚本像这样流图像:

<?php 

    $image_to_stream = '/path/outside/of/webroot/image.jpg'; 
    $cache_seconds = 2592000; // 30 days 

    header("Cache-Control: max-age=$cache_seconds"); 
    header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $cache_seconds) . ' GMT'); 
    header('Pragma: cache'); 
    header('Content-Type: image/jpg'); 
    header('Content-length: ' . filesize($image_to_stream)); 

    readfile($image_to_stream); 

?> 

然而,剧本似乎总是有“200 OK”状态,而且整个图像获取流。有没有办法解决这个问题,或者我应该采取另一种方法或什么?谢谢!

回答

0

您需要处理If-Modified-Since请求标头。

基本上,请在本地检查该文件的时间戳。如果自If-Modified-Since标题中指定的日期起已更改,请将其返回。否则,发送bac,一个304没有修改。

从RFC:

甲GET方法与一个If-Modified-Since标题和没有,如果它已经由于由如 - 给定的日期修改所标识的实体仅转移Range头部的请求Modified-Since标题。该算法用于确定这包括以下情况:

a)如果该请求通常会导致其它比 200(OK)状态,或如果传入的If-Modified-由于日期是 无效,响应任何与正常的GET完全相同。 晚于服务器当前时间的日期是 无效。 b)如果自从If-Modified-Since 日期以来该变体已被修改,则该响应与正常的GET完全相同。 c)如果自从有效的修改日期起,变体没有被修改,服务器应该返回304(不是 修改)响应。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

您可以发送这个PHP代码:

header('HTTP/1.1 304 Not Modified', true, 304); 
+0

这工作!非常感谢你! – Nick 2012-03-23 20:26:11

+1

但是,如果你想节省带宽,那么*不要忘记提供新的缓存控制/过期头!* – symcbean 2012-03-23 22:46:50

+0

@symcbean,同意! – Brad 2012-03-23 22:57:56