我正在尝试强制下载一个包含大量图像的 zip 文件。我正在使用 php 强制下载,它在 nginx 上运行。奇怪的是,当我使用 wget 下载文件时,它通常可以工作,但是当我尝试使用浏览器下载它时,文件最终只有几千字节。我尝试了多种文件大小,结果都差不多。我不认为这是一个超时错误,因为我尝试过减慢下载速度,但它总是停在同一个地方(在那个特定的文件上)。我不知道为什么它在 wget 上可以工作,但在浏览器上不行。我在多台电脑(使用不同的浏览器)和多个网络上尝试过,得到了相同的结果。我尝试过提供文件的 PHP 代码以及 php.ini 和 nginx 设置,但都无济于事。我非常感谢任何人的帮助或建议,这真的对我有很大帮助!
以下是强制下载的 PHP 代码:
ob_end_flush();
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.$name.'.zip"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($archive));
flush();
readfile($archive);
其中 $archive 是用户尝试下载的 zip 文件的路径。
答案1
您的网络服务器是否正在将 gzip 内容编码应用于您从 PHP 输出的文件(或者您是否已经在 PHP 本身中启用了它,例如zlib.output_compression
)?压缩已压缩的文件往往会使实际文件变大,因此,如果客户端读取脚本的 Content-Length 标头,它将在输出“较大”的压缩文件之前停止下载。
wget
不支持压缩,因此当您使用 wget 连接时,服务器不会尝试使用内容编码。尝试使用curl
,看看是否能得到损坏的文件。如果您使用 Chrome,Ctrl- Shift-J打开开发人员工具并转到“网络”选项卡。当它打开时,返回到您打开它的主窗口并点击链接下载文件。它应该在请求列表中创建一个您可以点击的条目,这将打开一个带有“标题”选项卡的子窗口,您可以在其中查看它是否包含Content-Encoding:
该部分中的行Response Headers:
。
顺便说一句,我认为你想在那里做ob_end_clean()
,而不是ob_end_flush()
因为向_flush()
客户端发送缓冲区中的任何东西,而_clean()
删除缓冲区和其中已有的任何标头。