0

訪問者がファイルをダウンロードできるようにする次のスクリプトがあります。

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 のライブ 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

これらが問題の原因である可能性はありますか?

ローカルホストでスクリプトを実行すると、すべて正常に動作します。また、このホストからファイルを直接ダウンロードすると、速度もスムーズでスムーズです。

私はこれについて本当に無知です。あなたの助けに感謝します。前もって感謝します。

アップデート:

問題をボトルネックに絞り込んだと思います。Web サーバーは自動的に出力を gzip 圧縮します。Content-LengthPHP スクリプトからヘッダーを削除すると、すべてがスムーズにダウンロードされ始めました。これは理にかなっています: の値はContent-Length、実際の gzip された出力ともはや一致しません。PHP では、圧縮されていないファイルサイズを読み取ってContent-Lengthヘッダーを設定しましたが、その後、Apache がそれを圧縮しました。これはおそらく、ブラウザーが詰まった場所です。

Content-Lengthこの質問に続いて、Web サーバーが出力を自動的に gzip 圧縮するときに正しいヘッダー サイズを設定する方法について質問します。

4

3 に答える 3

0

問題をボトルネックに絞り込みました。Webサーバーは自動的に出力をgzip圧縮します。PHPスクリプトからContent-Lengthヘッダーを削除すると、すべてがスムーズにダウンロードされ始めました。これは理にかなっています。Content-Lengthの値は、実際のgzip圧縮された出力と一致しなくなりました。PHPでは、圧縮されていないファイルサイズを読み取ってContent-Lengthヘッダーを設定しましたが、その後、Apacheがそれを圧縮します。これは、おそらくブラウザーが機能しなくなった場所です。

于 2010-02-23T08:51:18.813 に答える
0

gzip-Content-Encoding の設定を解除してみてください。

スクリプトの最初で使用ob_start()します。ヘッダーを設定する前に、@ob_end_clean();その直後に andを使用して、header("Content-Encoding:");入ってくる可能性のある gzip-Encoding を設定解除するように明示的に設定します。ファイルの最後に@ob_end_flush();.

出力バッファリング関数は、ヘッダー設定をよりフェイルセーフにするのに便利ですが、おそらく問題とは関係ありません。囲んでいる PHP コードが ob_gzhandler を使用していて、設定を解除する必要があったセットアップで問題が発生したことを覚えています。

于 2010-02-18T09:52:46.430 に答える
0

以下のコードを使用していますが、動作します。実を言うと、私は送信したすべてのヘッダーをまだ適切に理解していませんでしたが、まだ調査する時間がありませんでした。次の場所で説明を見つけました。

ソース:

http://www.opendesigns.org/forum/discussion/1437/php-download-counter/#pgbottom http://www.webdeveloper.com/forum/showthread.php?t=115815&highlight=PHP+download+counter http ://php.net/manual/en/function.header.php#83384

とにかくそれは動作します:

   /*
   TODO: still to be read and better understood.
   */

   //no caching (I don't uderstand what is this part useful for)
   header("Pragma: public"); //?
   header("Expires: 0"); //?
   header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); //?
   header("Cache-Control: private", false); //?

   //sending download file
   header("Content-Type: application/octet-stream"); //application/zip can use application/octet-stream that is more generic it works because in now days browsers are able to detect file anyway
   header("Content-Disposition: attachment; filename=\"" . basename($file_serverfullpath) . "\""); //ok
   header("Content-Transfer-Encoding: binary"); //?
   header("Content-Length: " . filesize($file_serverfullpath)); //ok
   readfile($file_serverfullpath);
于 2010-02-18T10:11:28.573 に答える