【发布时间】:2014-12-07 22:27:23
【问题描述】:
我是一个严重的新手,但在发帖之前我做了很多研究,所以希望你能提供帮助。
我正在尝试提供托管在 Apache 服务器上的大型 .zip 文件,大约 6.4 Gb。该文件在浏览器中显示完整下载,但实际上只下载了大约 500Mb。这似乎是一个非常普遍的问题,并且在网上找到了很多其他帖子和信息,但这个问题对我来说一直存在。
Large Zip file offered for download using php
IE download incomplete even though it claims success
Large zip downloads failing only in IE
我一直在使用 Chrome 39.0.2171.71 进行测试,但我在使用 FireFox 和 IE 时遇到了同样的问题。我认为我的文件比其他人发布的文件要大得多,因此他们的解决方案可能有助于解决问题,但没有解决根本问题。我有一个大约 400Mb 的第二个 .zip 文件,并且我成功使用了相同的 http 标头。
我发现的最有用的文章是:http://perishablepress.com/http-headers-file-downloads/,我已经从该来源复制了下面显示的大部分 php,因为该网站上的其他海报似乎已经这样做了。
我也尝试过使用 X-SendFile,但我认为我的虚拟主机没有安装适当的 Apache 模块。我花了一整天的时间在这上面工作,并且已经没有想法了!我已经成功使用了下载管理器,我不知道这是偶然还是什么,但我不想要求我的客户必须下载并安装单独的程序才能获取 .zip 文件。
<?php
// HTTP Headers for ZIP File Downloads
// set example variables
$filename = "huge.zip";
$filepath = "****";
// http headers for zip downloads
// header("X-Sendfile: $filepath$filename");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"".$filename."\"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filepath.$filename));
set_time_limit(0);
ob_end_flush();
@readfile($filepath.$filename);
?>
这是我运行上面的 php 时的响应标头
远程地址:76.162.142.242 请求网址:****/GetSW.php 请求方法:GET 状态码:200 OK 请求标头 接受:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 接受编码:gzip、deflate、sdch 接受语言:en-US,en;q=0.8 授权:基本****** 连接:保持活动 饼干:_ga=GA1.2.1176828605.1417985823 DNT:1 主办方:www.teamursa.org 参考:http://www.teamursa.org/****.html 用户代理:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 响应标头 缓存控制:公共 连接:保活 内容描述:文件传输 内容处置:附件;文件名="巨大的.zip" 内容长度:6720560824 内容传输编码:二进制 内容类型:应用程序/八位字节流 日期:2014 年 12 月 7 日星期日 22:16:57 GMT 过期:0 保活:超时=3,最大值=120 语用:public 服务器:阿帕奇 X-Powered-By:PHP/5.2.17【问题讨论】:
-
首先你不应该让 PHP 处理文件发送。而不是
readfile()将实际传输委托给Apache,这确实是应该使用mod_xsendfile的地方。您的 PHP 脚本没有实现部分/字节范围传输,因此恢复了 HTTP 下载。在 PHP 中重新实现任何这些都是非常不值得的。 -- 那么 PHP 脚本包装器的最初原因是什么? -
ftp 比 http 传输更大的文件友好,如果你有那个选项的话
-
我最好的猜测是你的 php 脚本会因为
max_execution_time设置 php.net/manual/en/info.configuration.php#ini.max-execution-time 而被杀死。因此,您的浏览器会得到 readfile 在那个时间窗口内设法发送的内容。 -
感谢 cmets!我添加并删除了 max_execution_time 设置,但没有任何效果。 FTP 很好用,但我不希望人们必须下载和安装 FTP 客户端。 @mario我可以尝试看看我的网络主机是否可以为我安装 mod_xsendfile ,我不确定这涉及到什么或者他们是否会这样做。我猜我不知道除了 php 包装器还能做什么。以前我只是在我的 html 中有一个指向 huge.zip 文件的链接,但 php 似乎是一种比使用 .htaccess 文件更有效的方式来指定 http 标头。
-
如果只是关于附加标头,请使用
mod_cern_meta和一个单独的huge.zip.meta文件,其中列出了要添加的原始HTTP 标头。或者,整个文件夹的RewriteRule huge.zip - [T=archive/zip]或普通的Header add "Content-Disposition: attachment"。
标签: php apache http http-headers zip