インターネットサービスでデータをダウンロードさせる処理に少し手こずったので、備忘録としてブログに記載。
そもそも、今回は、サービス内の特定データのみをzip圧縮してダウンロードさせる処理を行う時の仕組みです。
事前にzipファイルを作成して、URLで直リンクしてあげればいいと考える人は、少し浅はかですねえ。
URLでの直リンクは、セキュリティの観点から避けたいものです。
処理一覧
処理は以下のようなフローで行う事とします。
1. リンクをクリック
2. サーバー側でzip圧縮
3. ダウンロード処理
4. ダウンロード後にサーバーのzipファイルを削除
ダウンロードに関しては、データURLの痕跡を残さず、ダウンロード後は、データを削除するので、非常にセキュアな構造が作れます。
今回のプログラムの前提条件
データは複数のファイルが格納されているデータフォルダを圧縮する仕様です。
その際に使用するアーカイブタイプは、「zip」データを使用します。
これは、ダウンロードした後で、windowsでもmacでもデフォルトで使われているぐらい汎用性が高いので、zipを使うことにしてます。
最後に、このプログラムはPHPで実行されますが、Linux-OSで利用することを前提にしています。
もしzip圧縮プログラムがインストールされていない場合は、事前にインストールしておいてください。
ソースコード
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fileDownload</title>
</head>
<body>
<a href="download.php" target="_blank">ファイルをダウンロード</a>
</body>
</html>
<?php
makeZip();
function makeZip(){
$archivePath = "data/";
exec("zip -r download.zip " . $archivePath);
downloadFile("download.zip");
}
function downloadFile($path){
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header('Content-Length: ' . filesize($path));
echo file_get_contents($path);
unlink($path);
}
上記プログラムと同一階層に"data"フォルダを作成してその中に何かしらのデータを複数入れておきます。
解説
まず、Aリンクでdownload.phpにアクセスしますが、この時にダウンロードするデータに条件をつけたい場合は、GETクエリを付けて行えます。
target="blank"を指定して、ダウンロード後にページが切り替わらないところがポイントですね。
ちなみに、AJAXを使ってこの処理を行おうとすると、ポップアップブロックが出てしまうので、ブラウザセキュリティに注意してください。
アクセスを受けたPHP側では、まずzipアーカイブファイルを生成します。
この時の生成は、PHPコマンドではなく、execを使ってLINUXコマンドをたたきます。
個人的にこの方が高速に行えるような気がしているので、ほかのやり方でも問題ありません。
そして、アーカイブができたら、download関数にアーカイブしたパスを送ります。
download処理としては、header関数を使って、"apprication/zip"を指定して、file_get_contentsで作成したzipファイルをそのままechoすることで、実際にzipファイルをリンクした状態を作ります。
この時の小技ですが、
header('Content-Disposition: attachment; filename="'.basename($path).'"');
と記述することで、ファイル名をコントロールできます。
※サンプルでは、作成したarchiveと同じファイル名になります。
最後に、echoの後、unlinkすることで、作成したアーカイブデータを削除して完了になります。
ほかのサイトでは、"echo file_get_contents()"の箇所を"header("Location: ".$path);"としているケースがありますが、最後にファイルを削除しないのであれば、Locationで構わないのですが、echoすることで、unsync状態が作れて、完了後にきちんとデータ削除してくれるようになります。
最後に、とりあえず、複数のブラウザで確認しておきます。
・Google Chrome (mac) : ○
・Safari (mac) : ○
・Firefox (mac) : ○
windows系は確認していません。もしうまく動作しないブラウザがありましたら、教えてください。
とりあえず、結構アナログな手段ですが、こうした方法でダウンロードをセキュアに実装することが可能なので、便利に使ってみましょう。
0 件のコメント:
コメントを投稿