我有以下腳本,讓訪客下載文件:問題與下載:緩慢和/或失敗
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頭插件,我已經注意到了服務器將aditional的頭到響應:
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
難道這是問題的原因是什麼?
當我在本地主機上運行腳本時,一切正常。另外,當我直接從這個主機上下載文件時,速度也很好,流暢。
我對這一個真的很無知。你的幫助是明確的。先謝謝你。
UPDATE:
我想我已經到了瓶頸狹窄的問題。網絡服務器自動gzip壓縮輸出。當我從我的PHP腳本中刪除Content-Length
標題時,一切開始下載流暢。這是有道理的:Content-Length
的值與實際的gzip輸出不再匹配。在PHP中,我讀取未壓縮的文件大小以設置Content-Length
頭,但之後,Apache壓縮它,這可能是瀏覽器窒息的地方。
我會在網絡服務器自動gzip壓縮輸出時,關注如何設置正確的Content-Length
標題大小的問題。
嗨initall,謝謝你的迴應。我想我已經把問題縮小了。恐怕我無法覆蓋Content-Encoding標頭,因爲它是由網絡服務器設置的。換句話說,我相信Apache服務器被配置爲自動gzip壓縮輸出。所以,現在當我從我的PHP腳本中移除「Content-Length」頭時,所有工作都正常。這是有道理的,因爲PHP設置的內容長度與gzip壓縮文件的實際內容長度不再一致。這是瀏覽器可能窒息的地方。 – 2010-02-18 10:18:48
好的,聽起來很合理。爲了避免壓縮兩次,我也做過一次類似於主腳本頂部的操作: 'if(extension_loaded('zlib')&&(!(bool)ini_get('zlib.output_compression'))){ ob_start( 'ob_gzhandler'); } else { ob_start(); }' – initall 2010-02-18 11:11:15