傳統 XMLHttpRequest (XHR) 無法直接上傳檔案(FormData 為 HTML5 新增)。早期常用隱藏 <iframe> 模擬非同步上傳,不阻塞主頁面互動。
short_open_tag = On(舊碼相容)<input type="file">,target 指向隱藏 iframe,onchange 觸發 JS 檢查副檔名並 submit$_FILES,驗證、移動檔案,回傳 JavaScript 代碼操作父視窗 DOM(啟用送出鈕、填入檔名)<?php
// 設定上傳目錄(需可寫入)
$upload_dir = '/var/www/uploads/';
$web_upload_dir = '/uploads/';
$file = $_FILES['userfile'];
// 驗證:錯誤碼、副檔名、MIME、大小...
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
$allowed = ['jpg','png','gif','pdf'];
if (!in_array($ext, $allowed)) exit("alert('不允許的檔案類型');");
$new_name = uniqid('up_') . '.' . $ext;
$dest = $upload_dir . $new_name;
if (!move_uploaded_file($file['tmp_name'], $dest)) {
exit("alert('上傳失敗');");
}
// 回傳 JS 操作父視窗
echo "<script>";
echo "parent.document.getElementById('filename').value = '$new_name';";
echo "parent.document.getElementById('submit_btn').disabled = false;";
echo "parent.document.getElementById('preview').src = '$web_upload_dir$new_name';";
echo "</script>";
?>
<!-- 隱藏 iframe -->
<iframe name="upload_target" id="upload_target" style="display:none"></iframe>
<!-- 上傳表單 -->
<form action="upload.php" method="post" enctype="multipart/form-data" target="upload_target">
<input type="file" name="userfile" onchange="checkExt(this.value) && this.form.submit()">
</form>
<!-- 主表單 -->
<form action="submit.php" method="post">
<input type="hidden" name="filename" id="filename">
<textarea name="description"></textarea>
<button type="submit" id="submit_btn" disabled>送出</button>
</form>
HTML5 FormData + fetch()/XMLHttpRequest 可直接非同步上傳,支援進度條、拖放、多檔,為當前主流做法:
const formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('upload.php', {method:'POST', body:formData})
.then(r => r.json())
.then(data => { /* 更新 UI */ });
upload_max_filesize、post_max_size)php_flag engine off 禁止腳本執行