首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP + AJAX 實作非同步檔案上傳(iframe 方案)

     編輯:PHP 綜合知識

背景與挑戰

傳統 XMLHttpRequest (XHR) 無法直接上傳檔案(FormData 為 HTML5 新增)。早期常用隱藏 <iframe> 模擬非同步上傳,不阻塞主頁面互動。

系統需求

  • 現代瀏覽器(支援 iframe、FormData)
  • PHP 4.3+ / 5.x
  • short_open_tag = On(舊碼相容)

架構三層設計

  1. 上傳表單頁:含 <input type="file">,target 指向隱藏 iframe,onchange 觸發 JS 檢查副檔名並 submit
  2. 伺服端處理:PHP 接收 $_FILES,驗證、移動檔案,回傳 JavaScript 代碼操作父視窗 DOM(啟用送出鈕、填入檔名)
  3. 主表單頁:使用者填寫描述,隱藏欄位儲存上傳後檔名,最終送出完整資料

關鍵 PHP 處理流程

<?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>";
?>

前端 HTML 結構

<!-- 隱藏 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 */ });

安全性檢查清單

  • 副檔名 + MIME 雙重驗證
  • 檔案大小限制(PHP upload_max_filesize、post_max_size)
  • 重新命名避免覆蓋與路徑遍歷
  • 上傳目錄設定 php_flag engine off 禁止腳本執行
  • 圖片重新處理(GD/Imagick)移除潛在惡意代碼
  • 病毒掃描整合
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved