まず単純にボタンを押してPDFファイルをダウンロードする場合の
ダウンロードファイル名は以下のようにContent-Dispositionヘッダを
attachmentにし、filenameを設定することで可能です。
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
今回の要件では、
ブラウザで表示した上で、もしユーザによってダウンロードされた場合の
ファイル名を設定することなので、以下のようにattachmentをinlineに変更します。
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Length: ' . filesize($file_path));
readfile($file_path);
これでブラウザでの表示はできましたが、
いくつかのブラウザでダウンロード時のファイル名が正しく設定されませんでした。
そこでいくつかリクエスト時の処理を変更していきました。
##1.POSTメソッドではなくGETメソッドを使用する。
もともとPOSTメソッドでファイルNoを渡してPHP側でそのファイルNoに紐づく
ファイルを表示させるという処理を行っていたのですが、
Chromeでダウンロード時のファイル名が上手く設定されませんでした。
そこでGETメソッドに変えることでChromeでの動作が確認できました。
##2.URLの最終の「/」以下をダウンロード時のファイル名にする
①でChromeは動作確認がとれましたが、
今度はIE、Edgeでダウンロードする時に「無題.pdf」のような名前になってしまいました。
IEやEdgeではどうやらContent-dispositoionをinlineにした場合に、
filenameでの設定が上手くいかない場合があるようです。
調べていくと、URLの最終の「/」以下の部分がダウンロード時に有効とのことでした。
Laravelを使用している場合は、以下のようにルーティングを行います。
Route::get('/download/{download_name}', 'HoegeController@OpenPdf');
これでIEでの動作が確認できましたが、Edgeではやはり「無題.pdf」のようになりました。
この時GETパラメータとしてファイルNoを渡してPHP側で処理していましたが、
どうやらGETパラメータを渡すとEdgeでは正しくダウンロード名が設定できないようです。
##3.GETパラメータを使用しない
実装時点では一旦②まで対応してEdgeは対象外としていたのですが、
よくよく考えたらGETパラメータの代わりに、
ルーティングのURL途中にファイルNoを入れることで
PHP側での処理が可能だったな思います。時間があるとき直したい。。。
Route::get('/download/{file_no}/{download_name}', 'HoegeController@OpenPdf');
以上になります。