使用流程
- 建立 AJAX 物件
- 發送請求到伺服器獲取資料
- 伺服器回傳資料到瀏覽器
- 獲取資料並進行渲染或加工處理
1. 建立 XMLHttpRequest 物件
使用 XMLHttpRequest
物件來進行 AJAX 請求,並在 console 中查看 xhr
變數的內容。
1
| var xhr = new XMLHttpRequest();
|

重點:readyState
的數字代表不同的狀態
readyState 數字 |
代表涵義 |
0 |
XMLHttpRequest 物件已建立,但尚未連結 |
1 |
已調用 open() ,但尚未發送請求 |
2 |
偵測到已調用 send() |
3 |
正在加載中,可能資料量較大 |
4 |
資料已完全獲取 |
2. 使用 open()
連結資料
open()
方法用來設定請求的格式、網址以及同步或非同步。
1 2
| xhr.open('GET', 'https://hexschool.github.io/ajaxHomework/data.json', true);
|
格式 |
代表涵義 |
GET |
讀取資料 |
POST |
發送資料到伺服器 |
同步與非同步 |
代表涵義 |
true |
非同步,不會等待回應,程式碼會繼續執行 |
false |
同步,會等待回應後再繼續執行 |
由於調用了 open()
,此時 readyState
為 1。

3. 使用 send()
傳送資料
我們目前只需讀取資料,因此可傳送 null
。
- 使用
send()
後,readyState
會從 2(偵測到 send()
)變為 3(加載中),最終變為 4(資料獲取完成)。

4. 獲取資料
當使用非同步時,程式碼執行速度很快,可能在資料回傳之前就打印出 console
。
1 2 3 4
| var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://hexschool.github.io/ajaxHomework/data.json', true); xhr.send(null); console.log('xhr資料:', xhr.responseText);
|
可以使用 onload
方法來獲取資料:
1 2 3
| xhr.onload = function() { console.log('xhr資料:', xhr.responseText); };
|
再用 JSON.parse
將字串轉成物件並顯示在畫面上:
1 2 3 4 5 6 7
| var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://hexschool.github.io/ajaxHomework/data.json', true); xhr.send(null); xhr.onload = function() { var str = JSON.parse(xhr.responseText); document.querySelector('.text').textContent = str[0].name; };
|
使用同步請求可以先獲取資料,但資料量過大會影響使用者體驗。
1 2 3 4
| var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://hexschool.github.io/ajaxHomework/data.json', false); xhr.send(null); console.log('xhr資料:', xhr.responseText);
|
使用 JSON.parse
來轉換並顯示資料:
1 2
| var str = JSON.parse(xhr.responseText); document.querySelector('.text1').textContent = str[0].name;
|
HTTP 狀態碼
狀態碼 |
代表涵義 |
200 |
成功 (OK) |
3XX |
重新導向 (Redirection) |
404 |
找不到檔案或目錄 |
Cross-Origin Resource Sharing (CORS)
CORS 是一種機制,使用額外的 HTTP 標頭使得瀏覽器能夠獲取來自不同來源的資源。當請求的資源來自不同的網域、協定或通訊埠時,會建立一個跨來源 HTTP 請求。
因為安全性考量,跨來源請求受到限制。XMLHttpRequest
和 Fetch
都遵循同源政策(Same-Origin Policy),除非使用 CORS 標頭,否則只能請求與應用程式相同網域的資源。
簡而言之,在同一網域下 API 可以自由使用,但在不同網域下必須確認對方的後端是否開啟 CORS,否則會出現錯誤訊息。

測試 CORS 網址:cors-tester
AJAX 兩種傳送方式
- 傳統傳送方式
- JSON 傳送方式
這兩種方式的程式碼差異在於 setRequestHeader
的 Content-Type
和 send
傳送的值。
AJAX 傳統傳送方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <form action="index.html"> 帳號:<input class="email" type="text" name="email" id=""> <br> 密碼:<input class="password" type="password" name="password" id=""> <br> <input class="send" type="submit" value="send"> </form>
<script> var xhr = new XMLHttpRequest(); var send = document.querySelector('.send'); var text = document.querySelector('.text'); send.addEventListener('click', function(e) { e.preventDefault(); var emailVal = document.querySelector('.email').value; var passwordVal = document.querySelector('.password').value; xhr.open('POST', 'https://hexschool-tutorial.herokuapp.com/api/signup', true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(`email=${emailVal}&password=${passwordVal}`); xhr.onload = function() { var msg = JSON.parse(xhr.response); text.textContent = msg.message; }; }); </script>
|
AJAX JSON 傳送方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <form action="index.html"> 帳號:<input class="email" type="text" name="email" id=""> <br> 密碼:<input class="password" type="password" name="password" id=""> <br> <input class="send" type="submit" value="send"> </form>
<script> var xhr = new XMLHttpRequest(); var send = document.querySelector('.send'); var text = document.querySelector('.text'); send.addEventListener('click', function(e) { e.preventDefault(); var data = { email: document.querySelector('.email').value, password: document.querySelector('.password').value, }; xhr.open('POST', 'https://hexschool-tutorial.herokuapp.com/api/signup', true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.send(JSON.stringify(data)); xhr.onload = function() { var msg = JSON.parse(xhr.response); text.textContent = msg.message; }; }); </script>
|
不論是傳統還是 JSON 方式,傳送結果都會一致,具體使用哪一種需依據後端工程師的需求。
