在不支援 FormData 的舊環境,或需跨域提交表單時,利用 <form target="iframeName"> 搭配隱藏 <iframe> 可實現「無刷新提交、伺服器端回呼前端」的效果。本文提供最精簡可用範例。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>iframe AJAX 示範</title>
</head>
<body>
<form action="b.php" method="post" target="formTarget">
<input type="text" name="username" placeholder="輸入帳號">
<input type="submit" value="提交">
<span id="msg"></span>
</form>
<iframe name="formTarget" id="formTarget" style="display:none"></iframe>
</body>
</html>
<?php
$username = isset($_POST['username']) ? htmlspecialchars($_POST['username']) : '';
echo "<script>
parent.document.getElementById('msg').innerHTML = 'iframe 式 AJAX 呼叫成功!';
alert('您輸入的是:$username');
setTimeout(function(){ parent.window.location.reload(); }, 3000);
</script>";
?>
b.php 回傳的 HTML。<script> 執行,透過 parent.document 存取父頁面 DOM,更新提示訊息、彈出 alert、3 秒後重整父頁面。| 限制 | 影響 | 現代替代 |
|---|---|---|
| 同源策略 | 父頁與 b.php 必須同域,否則 parent.document 存取被阻擋 | CORS + fetch / postMessage |
| 無法獲取上傳進度 | 大檔上傳無進度條 | XHR2 / fetch + ReadableStream |
| 回呼耦合度高 | 伺服器端需輸出特定 JS 代碼 | 統一 JSON API,前端自行渲染 |
| 歷史紀錄汙染 | iframe 載入會產生瀏覽歷史 | history.replaceState 或 sandbox 屬性 |
若 b.php 部署於不同域,父頁改用 window.addEventListener('message', ...) 監聽,子頁面 parent.postMessage({type:'result', data:...}, 'https://parent.domain') 發送訊息,雙方驗證 event.origin 確保安全。