練習問題


前節では,ファイルアップロード画面を Drag & DropAjax によって改良する方法を学びました。この練習問題では,完成版の課題提出システムに,同じ考え方を自分で組み込んでみます。

ここでは common/common.php を読み込み,PDO接続変数 $dbhlogin_check() を使える状態で作業するものとします。ブラウザ側のチェックは利用者の操作性を高めるためのものであり,安全性のための最終確認は必ずPHP側でも行います。

課題1:Drag & Drop用の提出画面を作成する

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で表示上の変化を付けなさい。

課題2:Drag & Dropイベントを処理する

JavaScriptで次のイベントを処理しなさい。

  1. dragenterdragover で,ブラウザの既定動作を止め,ドロップ可能な状態にする。
  2. dragleave で,ドラッグ中の表示を元に戻す。
  3. drop で,event.dataTransfer.files からファイルを取り出す。
  4. ドロップ領域をクリックした場合は,隠してある input type="file" を開く。

課題3:送信前チェックを行う

JavaScript側で,選択またはドロップされたファイルについて次の確認を行いなさい。

課題4:Ajaxでアップロードする

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();

課題5:PHP側でJSONを返すアップロード処理を作成する

task_ajax_upload.php を作成し,次の条件を満たすようにしなさい。

  1. common/common.php を読み込み,login_check() でログイン済みユーザを確認する。
  2. header('Content-Type: application/json; charset=UTF-8') を指定し,結果をJSONで返す。
  3. UPLOAD_ERR_OK,ファイルサイズ,拡張子,MIMEタイプをPHP側でも確認する。
  4. 保存ファイル名は,利用者が送信したファイル名をそのまま使わず,random_bytes() などで衝突しにくい名前に変更する。
  5. PDOの prepare()execute() を使い,提出情報を task テーブルに登録する。

JavaScript側で拡張子やサイズを確認しても,その確認は利用者に改変される可能性があります。したがって,PHP側の確認を省略してはいけません。

解答例は 練習問題の解答例 に示します。


Copyright (c) 2014-2026 T.Kouya Laboratory @ Otemon Gakuin University. All rights reserved.