Ajax (Asynchronous JavaScript and XML) 讓網頁能在不重新整理的情況下與伺服器交換資料。本文拆解 Ajax 核心三步驟:建立 XMLHttpRequest 物件、發送非同步請求、處理伺服器回應,並提供可直接套用的模組化程式碼架構。
封裝為可重複使用的函式,依序嘗試標準建構子、MSXML2、Microsoft 實作:
function getXMLHttpRequest() { var xhr = null; try { xhr = new XMLHttpRequest(); // Firefox, Chrome, Safari, IE7+ } catch (e) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); // IE6 較新版 } catch (e) { try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); // IE6 舊版 } catch (e) { xhr = false; } } } return xhr; }
取得表單輸入值、驗證非空、建立請求物件、設定回調、發送請求:
function sendRequest() { var userName = document.getElementById("name").value; if (!userName) return; var xhr = getXMLHttpRequest(); if (!xhr) { alert("瀏覽器不支援 XMLHttpRequest"); return; } var url = "getusername.php?name=" + encodeURIComponent(userName); xhr.open("GET", url, true); // true = 非同步 xhr.onreadystatechange = updatePage; // 指定回調函式 xhr.send(null); // GET 請求 body 為 null }
檢查 readyState === 4 (請求完成),讀取 responseText 更新頁面:
function updatePage() { if (xhr.readyState === 4) { var response = xhr.responseText; document.getElementById("userinfo").value = response; } }
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Ajax 基礎範例</title> </head> <body> <input type="text" id="name" placeholder="輸入用戶名"> <button onclick="sendRequest()">查詢</button> <br><br> <textarea id="userinfo" rows="5" cols="40" readonly></textarea> <script> var xhr = null; // 全域變數持有請求物件 function getXMLHttpRequest() { /* 同前 */ } function sendRequest() { var userName = document.getElementById("name").value.trim(); if (!userName) return alert("請輸入用戶名"); xhr = getXMLHttpRequest(); if (!xhr) return alert("瀏覽器不支援 Ajax"); var url = "getusername.php?name=" + encodeURIComponent(userName); xhr.open("GET", url, true); xhr.onreadystatechange = updatePage; xhr.send(null); } function updatePage() { if (xhr.readyState === 4) { if (xhr.status === 200) { document.getElementById("userinfo").value = xhr.responseText; } else { document.getElementById("userinfo").value = "請求失敗: " + xhr.status; } } } </script> </body> </html>
<?php // 模擬資料庫查詢 $users = [ 'alice' => 'Alice Chen, 25, Taipei', 'bob' => 'Bob Wang, 30, Taichung', 'cindy' => 'Cindy Lin, 22, Kaohsiung' ]; $name = $_GET['name'] ?? ''; echo $users[$name] ?? "查無此用戶: $name"; ?>
發送 JSON 資料需設定 Content-Type 標頭:
xhr.open("POST", "api/user.php", true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify({ name: userName, action: "query" })); // 後端接收 $input = json_decode(file_get_contents('php://input'), true); $name = $input['name'] ?? '';
瀏覽器原生 fetch() 基於 Promise,語法更簡潔:
async function fetchUser(name) { try { const res = await fetch(`getusername.php?name=${encodeURIComponent(name)}`); const text = await res.text(); document.getElementById('userinfo').value = text; } catch (err) { document.getElementById('userinfo').value = '網路錯誤: ' + err.message; } }
| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| readyState 不會變成 4 | 網路中斷 / 伺服器無回應 | 設定 timeout、檢查伺服器日誌 |
| status = 0 | 跨域請求被瀏覽器攔截 | 設定 CORS 標頭或同源部署 |
| 中文亂碼 | 編碼不一致 | 統一 UTF-8、使用 encodeURIComponent |
| 快取導致舊資料 | GET 請求被瀏覽器快取 | 加入時間戳參數 ?t=Date.now() |
掌握 XMLHttpRequest 三步驟流程是理解 Ajax 運作機制的基石。現代開發建議優先使用 fetch 或 axios 等 Promise 基礎庫,搭配 JSON 介面、統一錯誤處理、TypeScript 型別定義,構建更健壯的前後端互動體驗。