IE不缓存视频(适用于Chrome)



在使用php + jsquery + javascript(例如index.php)构建的HTML页面上,视频标签具有另一个php页面的源,带有GET字段指定加载哪个视频(例如:"getfile.php ?文件"= 111)。

按钮切换正在播放的视频;例如javascript

var video = document.getElementById('flyover');
var source = video.getElementsByTagName('source')[0];
source.setAttribute('src', "getfile.php?file=222");

getfile.php发出HTTP头文件,然后是文件内容的fpassthru

...
header('Content-Type: video/mp4');
header('Content-Disposition: attachment; filename='.basename($file->FileName));
header('Content-Transfer-Encoding: binary');
$seconds_to_keep = ...
header ("Expires: " . gmdate("D, d M Y H:i:s", time() + $seconds_to_keep) . " GMT");
header('Cache-Control: public, max-age=' . $seconds_to_keep);
header('Content-Length: ' . filesize($filename));
fpassthru($fp);
exit;

用于确认报头的Fiddler代理:

#   Result  Protocol    Host    URL Body    Caching Content-Type
47  200 HTTP    ... /getfile.php?file=2639  10,113  public, max-age=31536000; Expires: Thu, 06 Aug 2015 20:20:30 GMT    video/mp4

测试操作:

  1. 加载页面
  2. 等待视频#1完成播放(Fiddler更新缓存信息从"-1"到"max-age/Expires"的详细信息)
  3. 视频#2按钮
  4. 等待视频#2播放完毕(Fiddler更新缓存信息)
  5. 视频#1按钮

在Chrome上,结果是视频#1立即开始播放(缓冲条显示一半加载,这是我在视频开始时看到的最多)。Fiddler没有向服务器显示一个新的"getfile"请求。

在IE 11中,有一个延迟,而视频#1缓冲(缓冲条显示零加载在视频开始)。Fiddler向服务器显示一个新的"getfile"请求。

IE的缓存设置为"自动"。(临时互联网文件/检查存储页面的新版本="自动")。缓存大小为250mb,每个视频约6mb,并且在开始测试之前清空缓存。

确认URL是完全相同的(根据fiddler,并在javascript中使用警告弹出)

问:还有什么可能影响IE无法缓存这些视频?

图片,通过相同的url获得,但具有不同的查询字段字段值,和不同的内容类型头,在IE缓存:如果退出浏览器,并重新启动浏览器,并去同一页面,Fiddler不显示任何"/getfile.php?Fileid =333"请求这些图像。(它确实显示了缓存清空后第一次加载页面时的请求)

php代码执行的唯一变化(对于图像和视频)是一个单独的if/else if语句,它控制发出什么Content-Type头。

也许是IE 11的缓存策略不缓存视频?

逻辑确实发出一个带有文件大小的Content-Length头,并且客户端internet选项缓存(250 mb)比文件大小(6 mb)大得多,因此它"应该"能够缓存它。磁盘空闲空间是多少gb

更新# 2

  • 重新启动IE,使用安全选项卡关闭或打开"启用保护模式"后,不会改变上述结果。
  • 将磁盘空间增加到最大(1024 MB)不会改变上述结果。
  • 设置IE的策略为"检查存储页面的新版本:Never"似乎不"粘":当关闭Internet选项,然后重新打开它,单选按钮已返回到"自动"。
  • 在IE测试确认缓存仍然在Chrome中正常工作后重复Chrome测试。

更新# 3

服务器上的php代码不测试HTTP_IF_MODIFIED_SINCE;我没有发送Last-Modified header。我以为maxage就足够了。如果存在Last-Modified, IE可能会更聪明地缓存视频文件。如果您有过在慢速服务器连接上处理视频的经验,并且成功地使用了一组特定的标头,那么您使用的方法的答案将是有用的。

试试吧,来自http://php.net/manual/en/function.header.php#85146:

$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"); 
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; 
}

最新更新