我有以下脚本让访问者下载文件:
header( 'Content-Type: application/octet-stream' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Content-Disposition: attachment; filename=' . $fileName );
header( 'Content-Length: ' . filesize( $filePath ) );
header( 'Content-Description: Download' );
header( 'Cache-Control: private' );
header( 'Pragma: no-cache' );
header( 'Expires: 0' );
readfile( $filePath );
exit();
它工作得不是很好。(我还将文件名放在引号中,结果相同)。
它的行为非常缓慢,有时甚至会停止下载。尤其是在 Opera 中,它会在 99% 的下载时停止。有时它甚至会立即显示 99% 已完成,然后开始下载并在 34% 左右停止。
服务器是一个共享主机,Mac OS X 服务器。
通过使用 Firefox 的 Live HTTP 标头插件,我注意到服务器在响应中添加了额外的标头:
HTTP/1.1 200 OK
Date: Thu, 18 Feb 2010 09:27:25 GMT
Server: Apache
X-Powered-By: PHP/5.2.12
Content-Transfer-Encoding: binary
Content-Disposition: attachment; filename=test.psd
Content-Length: 398635
Content-Description: Download
Cache-Control: private
Pragma: no-cache
Expires: 0
Content-Encoding: gzip // <-- expecially this one,
Vary: Accept-Encoding // <-- this one,
MS-Author-Via: DAV // <-- and this one
Keep-Alive: timeout=10, max=100
Connection: Keep-Alive
Content-Type: application/octet-stream
这些可能是问题的原因吗?
当我在本地主机上运行脚本时,一切正常。另外,当我直接从这个主机下载文件时,速度也很流畅。
我真的对这个一无所知。你的帮助很受欢迎。先感谢您。
更新:
我想我已经将问题缩小到瓶颈。网络服务器自动 gzip 压缩输出。当我Content-Length
从我的 PHP 脚本中删除标题时,一切都开始顺利下载。这是有道理的: 的值Content-Length
不再与实际的 gzip 输出匹配。在 PHP 中,我读取了未压缩的文件大小来设置Content-Length
标题,但之后,Apache 将其压缩,这可能是浏览器阻塞的地方。
Content-Length
我将在这个问题之后提出一个问题,即当网络服务器自动 gzip 压缩输出时如何设置正确的标头大小。