代码之家  ›  专栏  ›  技术社区  ›  ToolmakerSteve

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

  •  1
  • ToolmakerSteve  · 技术社区  · 12 年前

    在使用php+jsquery+javascript(例如index.php)构建的HTML页面上,视频标记的源是另一个php页面,GET字段指定要加载的视频(例如“getfile.php?file=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”更新为“最大年龄/过期”详细信息)
    3. 视频#2按钮
    4. 等待视频#2播放完毕(Fiddler更新缓存信息)
    5. 视频#1按钮

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

    在IE 11上,视频#1缓冲时存在延迟(缓冲条显示视频开始时加载为零)。Fiddler确实向服务器显示了一个新的“getfile”请求。

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

    确认URL完全相同(根据fiddler的说法,并使用javascript中的警告弹出窗口)。

    Q: 还有什么可能影响IE缓存这些视频的失败?

    更新

    图片,通过相同的url获取,但具有不同的查询字段fileid值和不同的Content-Type标头,在IE中进行缓存:如果退出浏览器,重新启动浏览器,并转到相同的页面,Fiddler不会显示这些图片的任何“/getfile.php?fileid=333”请求。(它确实在缓存清除后首次加载页面时显示了这些请求。)

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

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

    该逻辑确实会发出带有文件大小的Content-Length标头,并且客户端internet选项缓存(250 mbs)比文件大小(6 mbs)大得多,因此它“应该”能够缓存它。磁盘空间可用很多GB。

    更新#2

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

    更新#3

    服务器上的php代码未测试HTTP_IF_MODIFIED_SINCE;我没有发送Last Modified标头。我以为最大化就足够了。如果存在“上次修改”,IE可能会更聪明地缓存视频文件。如果您有过通过慢速服务器连接观看视频的经验,并且已经成功使用了一组特定的标头,那么您使用的方法的答案将非常有用。

    1 回复  |  直到 12 年前
        1
  •  1
  •   user3942918    12 年前

    试试看,从 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; 
    }