前節では,ファイルアップロード画面を Drag & Drop と Ajax によって改良する方法を学びました。この練習問題では,完成版の課題提出システムに,同じ考え方を自分で組み込んでみます。
ここでは common/common.php を読み込み,PDO接続変数 $dbh と login_check() を使える状態で作業するものとします。ブラウザ側のチェックは利用者の操作性を高めるためのものであり,安全性のための最終確認は必ずPHP側でも行います。
task.php を参考にして,task_dragdrop.php を作成しなさい。通常の <input type="file"> を画面にそのまま表示するのではなく,次のようなドロップ領域を作成します。
<div id="drop_zone" class="drop-zone">
ここに pdf, zip, txt ファイルをドラッグ&ドロップしてください。<br>
またはクリックしてファイルを選択してください。
</div>
<input type="file" id="task_file" name="task_file" accept=".pdf,.zip,.txt" hidden>
ドロップ領域には,ドラッグ中であることが分かるようにCSSで表示上の変化を付けなさい。
JavaScriptで次のイベントを処理しなさい。
dragenter と dragover で,ブラウザの既定動作を止め,ドロップ可能な状態にする。dragleave で,ドラッグ中の表示を元に戻す。drop で,event.dataTransfer.files からファイルを取り出す。input type="file" を開く。JavaScript側で,選択またはドロップされたファイルについて次の確認を行いなさい。
pdf, zip, txt のいずれかであること。FormData に課題名,コメント,ファイルを追加し,fetch() を使って task_ajax_upload.php に送信しなさい。通常のフォーム送信とは異なり,ページ全体を再読み込みせず,PHPから返されたJSONを読んで結果メッセージを表示します。
const formData = new FormData();
formData.append('name', document.getElementById('name').value);
formData.append('word', document.getElementById('word').value);
formData.append('task_file', selectedFile);
const response = await fetch('task_ajax_upload.php', {
method: 'POST',
body: formData
});
const result = await response.json();
task_ajax_upload.php を作成し,次の条件を満たすようにしなさい。
common/common.php を読み込み,login_check() でログイン済みユーザを確認する。header('Content-Type: application/json; charset=UTF-8') を指定し,結果をJSONで返す。UPLOAD_ERR_OK,ファイルサイズ,拡張子,MIMEタイプをPHP側でも確認する。random_bytes() などで衝突しにくい名前に変更する。prepare() と execute() を使い,提出情報を task テーブルに登録する。JavaScript側で拡張子やサイズを確認しても,その確認は利用者に改変される可能性があります。したがって,PHP側の確認を省略してはいけません。
解答例は 練習問題の解答例 に示します。