JavaScript
Browser APIs
Fetch / AJAX
เรียนรู้แนวคิด AJAX และการส่ง HTTP request ด้วย fetch — ครอบคลุม GET, POST, การจัดการ error ด้วย response.ok และ try/catch
AJAX คืออะไร
AJAX (Asynchronous JavaScript and XML) คือเทคนิคการส่ง HTTP request จาก JavaScript โดยไม่ต้อง reload หน้าเว็บ — ทำให้เว็บแสดงข้อมูลใหม่ได้โดยผู้ใช้ไม่รู้สึกว่าหน้ากระพริบหรือโหลดซ้ำ ในปัจจุบัน `fetch` คือ API มาตรฐานที่ใช้ทำ AJAX แทน `XMLHttpRequest` รุ่นเก่า
| XMLHttpRequest (เดิม) | fetch (ปัจจุบัน) | |
|---|---|---|
| syntax | verbose, callback-based | สั้นกว่า, Promise-based |
| async/await | ไม่รองรับโดยตรง | รองรับเต็มที่ |
| error handling | ซับซ้อน | ใช้ .catch() หรือ try/catch |
| ใช้ใน | โค้ดเก่า (legacy) | โค้ดใหม่ทั้งหมด |
GET request — ดึงข้อมูลจาก API
รูปแบบพื้นฐานของ GET request ด้วย `fetch`: 1. เรียก `fetch(url)` — คืน Promise ของ Response 2. เรียก `.json()` บน response — คืน Promise ของข้อมูล 3. นำข้อมูลไปใช้งาน ควรใช้ `async/await` เพื่อให้โค้ดอ่านง่าย
jsonplaceholder.typicode.com คือ API สำหรับทดสอบ — ไม่ต้อง login และรองรับ CORS
async function loadUser() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const user = await response.json();
console.log(user.name); // "Leanne Graham"
document.querySelector("#name").textContent = user.name;
}
loadUser();POST request — ส่งข้อมูลไปยัง API
GET request ไม่มี body — แต่ POST ต้องระบุ: - `method: "POST"` - `headers` บอกว่า body เป็น JSON - `body: JSON.stringify(data)` แปลง object เป็น string ก่อนส่ง
headers บอก server ว่า body เป็น JSON — ถ้าไม่ใส่ server บางตัวจะอ่าน body ไม่ออก
async function createPost() {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "บทความใหม่",
body: "เนื้อหาบทความ",
userId: 1,
}),
});
const result = await response.json();
console.log(result.id); // ID ของ post ที่สร้าง
}
createPost();การจัดการ error — response.ok และ try/catch
`fetch` จะ reject Promise เฉพาะเมื่อเกิด network error เช่น ไม่มีอินเทอร์เน็ต — แต่ถ้า server ตอบกลับด้วย 404 หรือ 500 จะถือว่า **สำเร็จ** และ Promise จะ resolve ต้องตรวจ `response.ok` เองเสมอ — `response.ok` เป็น `true` เมื่อ status code อยู่ในช่วง 200–299
pattern นี้จัดการทั้ง network error (catch) และ HTTP error (response.ok) — ควรใช้ทุกครั้ง
async function loadData(id) {
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error("โหลดข้อมูลไม่สำเร็จ:", error.message);
}
}ข้อควรระวัง
- **fetch ไม่ reject บน HTTP error** — 404, 500 ไม่ทำให้ Promise reject ต้องตรวจ `response.ok` เอง
- **CORS** — ถ้า API อยู่ต่าง domain server ต้องตั้งค่า CORS header ยอมรับ request จาก domain ของเรา — ถ้าไม่ยอมจะ error ฝั่ง browser
- **ลืม await** — เรียก `response.json()` โดยไม่มี `await` จะได้ Promise object ไม่ใช่ข้อมูล
- **อย่า fetch ใน render loop** — ถ้า fetch อยู่ใน event handler ที่ถูกเรียกซ้ำบ่อย ควรใช้ debounce หรือ flag เพื่อป้องกัน request ซ้ำ