PHP構築しているシステムで、ファイルダウンロードする仕組みを構築中にheader関数の"Content-type"記述で若干足止めを食らったので、その時の解決法を備忘録として残しておきます。
ダウンロードの内容は、Microsoft製のPowerPointファイルで拡張子が「pptx」のデータをシステムからダウンロードさせる仕様だったのですが、ダウンロードまでは問題なくできたのですが、そのファイルをPowerPointで開こうとすると、ヘッダが壊れているとの以下のようなエラーメッセージが表示されてしまいます。
どうやらPHPでのヘッダ情報の記述が足りていなかったようですね。
エラーコード
$path = "data/template.pptx";
header("Content-Type: application/pptx");
header("Content-Disposition: attachment; filename=Download.pptx");
readfile($pptx);
どうやら"Content-Type"で拡張子を指定すればいいとだけ考えていた僕が浅はかだったようです。
成功パターン
$path = "data/template.pptx";
header( 'Pragma: public' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
header( 'Cache-Control: private', false );
header( 'Content-Description:File Transfer' );
header( 'Content-Disposition: attachment; filename=Download.pptx');
header( 'Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation' );
header( 'Content-Transfer-Encoding: binary');
header( 'Content-Length: ' . filesize($path) );
readfile($path);
非常に長いプログラムになってしまいましたが、重要なポイントは、"Content-Length:"の箇所だけのようです。
ここで、ファイルの総容量を指定することで、エラーは無くなるようです。
ただ、他の設定もどうやらセオリー(おまじない)として記述しておいた方が良さそうなので、とりあえず書いてあります。
あとがき
[PHP] 外部APIからファイルデータを取得した時の振る舞いについて
以前書いた記事でも、content-type関連の事をネタにしていたのですが、ここにもちゃんとlengthが記述されていました。
ネットワークにおけるヘッダ情報についてはこうした事をきちんと理解しておかなければいけないようですね。
肝に命じて、コーディングするとしましょう。
0 件のコメント:
コメントを投稿