Mấy năm trước, mỗi lần đụng tới API là mình lại thấy lấn cấn với đám XMLHttpRequest rườm rà. Viết một cái HTTP request đơn giản mà tốn cả chục dòng code, lại còn dễ dính lỗi callback lồng nhau. Giờ thì khác rồi, từ khi có Fetch API và cú pháp async/await ngon lành, việc gọi REST API bằng JavaScript đã nhẹ nhàng hơn hẳn. Đây không chỉ là công nghệ mới, mà là một sự thay đổi tư duy giúp code của bạn sạch sẽ, dễ đọc và đặc biệt là xử lý lỗi “chuẩn không cần chỉnh”. Trong bài chia sẻ này, Phạm Hải sẽ giúp bạn “bắt mạch” chi tiết công cụ này. Nếu bạn đang trong quá trình Học JavaScript cơ bản cho người mới 2026, việc làm chủ Fetch API chắc chắn là tấm vé thông hành bắt buộc để bạn tiến xa hơn trong nghề web.
Quên XMLHttpRequest đi, đây là cách gọi API “sạch-đẹp” nhất 2026!
Trả lời nhanh: Fetch API là một Web API hiện đại được tích hợp sẵn trong các trình duyệt và Node.js, cung cấp giao diện linh hoạt dựa trên Promise để thực hiện các HTTP request, thay thế hoàn hảo cho XMLHttpRequest cũ kỹ.
Làm việc với JavaScript bất đồng bộ đã thay đổi rất nhiều trong những năm qua. Hồi xưa, để lấy dữ liệu từ một endpoint API, chúng ta phải thiết lập hàng loạt các event listener phức tạp. Nhưng nay, cách dùng Fetch API trong JavaScript đã trở thành tiêu chuẩn công nghiệp không thể thay thế.
Fetch API cung cấp phương thức fetch() toàn cục, cho phép bạn thực hiện các lệnh gọi mạng một cách thanh lịch. Nó sử dụng Promise cốt lõi, giúp cấu trúc code rõ ràng và tránh được tình trạng “callback hell” khét tiếng. Đặc biệt, từ phiên bản Node.js 18 trở lên, Fetch đã được hỗ trợ native. Điều này có nghĩa là bạn có thể viết code gọi API trên cả Front-end lẫn Back-end với cùng một cú pháp mà không cần cài thêm bất kỳ thư viện nào. Đây thực sự là một cuốn hướng dẫn Fetch API cho người mới bắt đầu hoàn hảo để bạn tự tin bước vào thế giới lập trình web động.
Ví dụ Fetch API GET đầu tiên: Lấy danh sách sản phẩm
Trả lời nhanh: Để thực hiện một GET request, bạn chỉ cần gọi fetch(url). Mặc định, Fetch API sẽ sử dụng phương thức GET để lấy dữ liệu từ server về mà không cần cấu hình thêm.
Hãy bắt đầu với ví dụ Fetch API GET kinh điển nhất: kéo dữ liệu từ một RESTful API về giao diện. Khi bạn truyền một URL vào hàm fetch(), trình duyệt sẽ tự động phát đi một yêu cầu GET.
async function fetchProducts() {
try {
const response = await fetch('https://api.example.com/products');
if (!response.ok) {
throw new Error(`Lỗi gọi API: ${response.status}`);
}
const products = await response.json();
console.log("Danh sách sản phẩm:", products);
} catch (error) {
console.error("Đã xảy ra lỗi:", error);
}
}
Sau khi lấy được mảng dữ liệu JSON về, bạn thường sẽ muốn hiển thị nó lên giao diện người dùng. Lúc này, việc kết hợp với các JavaScript Array methods map filter reduce sẽ giúp bạn lặp qua danh sách sản phẩm và lọc ra những item cần thiết cực kỳ nhanh chóng. Tiếp đó, bạn chỉ cần dùng các kỹ thuật DOM JavaScript thao tác phần tử HTML để in chúng ra màn hình. Thậm chí, nếu bạn đang nhận dự án lập trình rest api cho wordpress, bạn hoàn toàn có thể dùng đúng đoạn code GET này để kéo danh sách bài viết mới nhất ra trang chủ một cách mượt mà.
Giải mã Response trả về: response.ok, response.status, và response.json()
Trả lời nhanh: Khi Promise của Fetch hoàn thành, nó trả về một Response object. Bạn bắt buộc phải kiểm tra response.ok hoặc Status code trước khi gọi response.json() để parse dữ liệu.
Điểm khiến nhiều bạn mới bỡ ngỡ nhất là Fetch API không trực tiếp trả về cục dữ liệu ngay lập tức. Thay vào đó, nó trả về một Response object chứa toàn bộ siêu dữ liệu (metadata) của phản hồi từ server.
response.status: Là HTTP Status code (ví dụ 200 là thành công, 404 là Not Found, 500 là lỗi server).response.ok: Một thuộc tính boolean cực kỳ hữu dụng. Nó sẽ trả vềtruenếu status code nằm trong dải 200-299. Đây là “chốt chặn” an toàn nhất để biết request có thực sự thành công hay không.response.json(): Một phương thức bất đồng bộ khác dùng để đọc luồng dữ liệu của Body request và dịch nó thành object JavaScript.
Dữ liệu truyền tải qua mạng luôn ở dạng chuỗi văn bản thuần (text/stream). Phương thức json() đóng vai trò như một thông dịch viên, biến chuỗi vô hồn đó thành cấu trúc dữ liệu mà JavaScript có thể thao tác được.
Tại sao async/await là “chân ái” cho Fetch API?
Trả lời nhanh: Kết hợp Fetch API với async/await giúp mã bất đồng bộ trông giống như mã đồng bộ, giúp luồng code dễ đọc từ trên xuống dưới, dễ debug và quản lý tốt hơn so với dùng chuỗi .then().
Mặc dù bạn hoàn toàn có thể dùng chuỗi .then().catch() với Fetch API và Promise, nhưng ở thời điểm hiện tại, Fetch API với async/await mới thực sự là tiêu chuẩn vàng. Việc sử dụng async/await giúp loại bỏ các hàm callback lồng nhau, làm cho code của bạn đọc y hệt như những dòng lệnh đồng bộ bình thường.
Những tính năng mạnh mẽ này đều được xây dựng dựa trên nền tảng của ES6. Nếu bạn chưa cập nhật, mình khuyên bạn nên xem qua bài viết về ES6 JavaScript tính năng mới cần biết để hiểu sâu hơn về bản chất của Promise. Để nắm bắt tường tận cơ chế chờ đợi (await) đằng sau hậu trường, bài viết phân tích Async Await Promise JavaScript dễ hiểu của mình sẽ giải đáp mọi thắc mắc cho bạn. Tại Phạm Hải, qua quá trình review code cho nhiều dự án, chúng mình nhận thấy việc dùng async/await giúp giảm thiểu tới 40% các lỗi logic liên quan đến luồng dữ liệu.
Không chỉ GET, các phương thức POST, PUT, DELETE cũng dễ như ăn kẹo
Trả lời nhanh: Bằng cách tùy chỉnh tham số thứ hai (options object) trong hàm fetch(), bạn có thể dễ dàng thay đổi method thành POST, PUT, hoặc DELETE để thực hiện các thao tác CRUD.
Hệ thống RESTful API không chỉ sinh ra để đọc dữ liệu. Để xây dựng một ứng dụng thực tế, bạn cần biết cách tạo mới, cập nhật và xóa tài nguyên. Tin vui là Fetch API xử lý việc này với một cú pháp cực kỳ nhất quán. Bạn chỉ cần truyền thêm một object cấu hình (options) vào tham số thứ hai của hàm fetch().
Gửi dữ liệu JSON với Fetch API POST để tạo tài nguyên mới
Trả lời nhanh: Để gửi dữ liệu lên server, hãy thiết lập method: 'POST', thêm header Content-Type: application/json và bắt buộc chuyển đổi dữ liệu thành chuỗi bằng JSON.stringify() trong body.
Khi có người dùng đăng ký tài khoản hoặc gửi form liên hệ, bạn sẽ cần dùng đến ví dụ Fetch API POST. Dưới đây là đoạn code chuẩn mực:
async function createNewUser(userData) {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(userData) // Bắt buộc phải stringify
};
const response = await fetch('https://api.example.com/users', options);
if (!response.ok) throw new Error("Không thể tạo user");
return await response.json();
}
Lỗi phổ biến nhất ở đây là quên JSON.stringify() cho thuộc tính body. Trình duyệt sẽ không tự động dịch object JavaScript của bạn thành JSON đâu. Nếu bạn đang hừng hực khí thế muốn thực hành ngay mà ngặt nỗi chưa có server backend nào để test, bạn có thể tham khảo mẹo Tạo API backend bằng AI trong 10 phút để tự dựng cho mình một endpoint API xịn sò, tha hồ test các phương thức POST nhé.
Cập nhật và Xóa dữ liệu với PUT và DELETE
Trả lời nhanh: Các thao tác Fetch API PUT DELETE hoàn toàn tương tự như POST, bạn chỉ cần đổi thuộc tính method và đính kèm ID của tài nguyên trực tiếp vào endpoint URL.
Thao tác Fetch API PUT DELETE đóng vai trò hoàn thiện chu trình CRUD của bạn.
- Với PUT (hoặc PATCH), bạn gửi kèm
bodychứa dữ liệu mới lên endpoint có chỉ định ID cụ thể (ví dụ:api/users/123). - Với DELETE, mọi thứ còn đơn giản hơn. Bạn thường không cần gửi
body. Chỉ cần setmethod: 'DELETE'là server sẽ tự hiểu bạn muốn “tiêu diệt” tài nguyên tại URL đó.
| Phương thức HTTP | Mục đích chính | Yêu cầu Body request |
|---|---|---|
| POST | Tạo mới tài nguyên | Bắt buộc có |
| PUT/PATCH | Cập nhật toàn bộ/một phần | Bắt buộc có |
| DELETE | Xóa tài nguyên | Thường là Không |
Bí quyết gửi Headers và Authorization Token
Trả lời nhanh: Việc gửi header với Fetch API được thực hiện thông qua thuộc tính headers trong object cấu hình, đóng vai trò sống còn để truyền các token xác thực danh tính người dùng.
Trong môi trường thực tế, 90% các endpoint API có giá trị đều được khóa lại bởi các lớp bảo mật. Việc gửi header với Fetch API là kỹ năng bạn dùng mỗi ngày. Bạn sẽ sử dụng thuộc tính Headers để truyền các thông tin metadata cấu hình, đặc biệt là Bearer Token.
Thông thường, sau khi người dùng đăng nhập thành công, server sẽ trả về một chuỗi token. Bạn có thể tận dụng Local Storage Session Storage JavaScript để lưu trữ an toàn token này ở phía trình duyệt. Sau đó, trong mỗi request tiếp theo, bạn gọi nó ra và nhét vào header:
const token = localStorage.getItem('myAccessToken');
const options = {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
};
const response = await fetch('https://api.example.com/private-data', options);
Xử lý lỗi Fetch API như một “lão làng”: Từ try...catch đến response.ok

Trả lời nhanh: Xử lý lỗi với Fetch đòi hỏi chiến thuật hai lớp: dùng try...catch để bắt lỗi mạng (mất kết nối) và kiểm tra thủ công response.ok để bắt các lỗi HTTP (404, 500) từ server.
Đây là cái bẫy mà hầu hết các bạn Junior đều dẫm phải. Khác với các thư viện bên thứ ba, Fetch API có một đặc tính rất nguyên thủy: nó chỉ ném ra lỗi (reject Promise) khi mạng bị đứt hoặc DNS không phân giải được. Còn nếu server vẫn sống và trả về lỗi 404 (Không tìm thấy) hay 500 (Lỗi server nội bộ), Fetch vẫn coi đó là một request… thành công! Do đó, xử lý lỗi Fetch API cần một tư duy phòng thủ nhiều lớp.
Bẫy lỗi mạng (Network Error) với try...catch
Trả lời nhanh: Bọc toàn bộ khối lệnh gọi Fetch bằng try...catch để tóm gọn các lỗi vật lý do đứt cáp, rớt mạng wifi hoặc sai địa chỉ URL hoàn toàn.
Lớp phòng thủ đầu tiên và cơ bản nhất là try...catch. Bất cứ khi nào bạn dùng từ khóa await, hãy đặt nó trong một khối try.
try {
const response = await fetch('https://api.example.com/data');
// Code xử lý tiếp theo...
} catch (error) {
console.error("Lỗi mạng nghiêm trọng. Vui lòng kiểm tra kết nối internet:", error);
}
Khối catch này hoạt động như một cái lưới an toàn, cứu ứng dụng của bạn khỏi cảnh trắng màn hình khi người dùng đột ngột đi vào vùng mất sóng 4G hoặc server bị sập nguồn không thể phản hồi.
Phân biệt lỗi HTTP (404, 500) bằng cách kiểm tra response.ok
Trả lời nhanh: Ngay sau khi nhận được response, bạn phải kiểm tra if (!response.ok) và chủ động dùng lệnh throw new Error() để đẩy các lỗi HTTP xuống khối catch xử lý chung.
Lớp phòng thủ thứ hai nằm ngay sau dòng lệnh fetch. Như mình đã phân tích, Status code dạng 4xx hay 5xx không làm Fetch tự động nhảy vào catch. Bạn phải tự tay làm điều đó.
const response = await fetch(url);
if (!response.ok) {
// Chủ động ném lỗi nếu status không phải 2xx
throw new Error(`Lỗi HTTP! Trạng thái server trả về: ${response.status}`);
}
const data = await response.json();
Tại Phạm Hải, quy chuẩn code (coding convention) của team mình luôn bắt buộc phải có dòng if (!response.ok) này cho mọi request. Nó giúp bạn chủ động kiểm soát luồng lỗi, từ đó hiển thị các thông báo (toast message) thân thiện cho người dùng thay vì để ứng dụng chạy tiếp và crash vì dữ liệu trả về bị undefined.
Kinh nghiệm xử lý lỗi CORS đau đầu cho người mới
Trả lời nhanh: Lỗi CORS xảy ra khi trình duyệt chặn request từ một domain khác vì lý do bảo mật. Cách giải quyết chuẩn xác nhất là cấu hình lại header CORS từ phía server backend.
CORS (Cross-Origin Resource Sharing) đích thị là “nỗi ám ảnh” của mọi lập trình viên Front-end. Bạn viết code gọi API hoàn hảo, nhưng tab Network báo đỏ chót và console văng ra dòng chữ “Blocked by CORS policy”. Hãy khắc cốt ghi tâm: CORS là cơ chế bảo mật của trình duyệt, nó không phải là lỗi của Fetch API.
Nhiều bạn lên mạng tìm hiểu và thử thêm mode: 'no-cors' vào cấu hình fetch. Đừng làm vậy! Cách này chỉ làm trình duyệt bỏ qua cảnh báo, nhưng bạn sẽ nhận lại một “opaque response” (phản hồi mờ) và hoàn toàn không thể đọc được dữ liệu JSON bên trong. Giải pháp triệt để và duy nhất là bạn phải làm việc với team Backend, yêu cầu họ thêm domain Front-end của bạn vào danh sách Access-Control-Allow-Origin trên server.
Đặt lên bàn cân: Fetch API, XMLHttpRequest và Axios
Trả lời nhanh: Fetch API là giải pháp hiện đại, nhẹ nhàng và có sẵn. Axios cung cấp nhiều tính năng tự động hóa hơn nhưng yêu cầu cài đặt thêm. XMLHttpRequest thì đã quá lỗi thời và không nên dùng nữa.
Hệ sinh thái JavaScript luôn có nhiều con đường để đi đến cùng một đích. Việc lựa chọn công cụ gọi API nào phụ thuộc lớn vào quy mô dự án. Dựa trên các bản cập nhật mới nhất của năm 2026, hãy cùng phân tích xem đâu là lựa chọn tối ưu.
Fetch API so sánh với “ông già” XMLHttpRequest
Trả lời nhanh: Fetch API vượt trội hoàn toàn so với XMLHttpRequest nhờ cú pháp ngắn gọn, hỗ trợ Promise native và không bị phụ thuộc vào kiến trúc callback rườm rà.
Khi làm bài toán Fetch API so sánh XMLHttpRequest, kết quả là một chiến thắng áp đảo cho Fetch. XMLHttpRequest (XHR) là công nghệ ra đời từ đầu những năm 2000. Để dùng nó, bạn phải khởi tạo object, mở kết nối, thiết lập các hàm onreadystatechange, và tự quản lý các trạng thái từ 0 đến 4. Nó quá cồng kềnh.
Fetch API ra đời chính là để đưa XHR vào viện bảo tàng. Nó cung cấp một API sạch sẽ, hướng đối tượng với Request và Response rõ ràng. Các tài liệu từ MDN trong năm 2026 còn cho thấy Fetch đang tiếp tục được mở rộng với các tính năng như fetchLater() để tối ưu hóa việc gửi dữ liệu ngầm khi người dùng đóng tab. Không có bất kỳ lý do kỹ thuật nào để bạn dùng lại XHR cho các dự án mới hiện nay.
Khi nào thì nên dùng thư viện Axios thay cho Fetch API?
Trả lời nhanh: Nên dùng Axios cho các dự án Enterprise cần cấu hình phức tạp, interceptors, tự động parse JSON. Dùng Fetch cho các dự án ưu tiên sự gọn nhẹ, không muốn phụ thuộc thư viện ngoài.
Dù Fetch API rất xuất sắc, nhưng Axios vẫn giữ được vị thế của mình. Axios ghi điểm nhờ khả năng tự động parse JSON (bạn không cần gọi .json()), tự động ném lỗi nếu status code là 4xx/5xx (bỏ qua được bước check response.ok), và đặc biệt là tính năng Interceptors cực kỳ mạnh mẽ giúp bạn đính kèm token tự động vào mọi request hoặc xử lý logic refresh token tập trung.
Tuy nhiên, xu hướng phát triển web năm 2026 đang dịch chuyển mạnh mẽ về các giải pháp “Zero-dependency” (không phụ thuộc). Fetch API do được tích hợp sẵn (built-in) nên giúp giảm đáng kể dung lượng bundle của ứng dụng (Axios nặng khoảng 13KB). Nếu bạn làm dự án nhỏ đến vừa, Fetch kết hợp với một vài hàm helper tự viết là quá đủ. Nhưng nếu bạn đang maintain một hệ thống đồ sộ với hàng trăm endpoint, Axios vẫn là một khoản đầu tư xứng đáng.
Tóm lại, Fetch API kết hợp với async/await chính là bộ đôi công cụ sắc bén nhất để làm việc với REST API trong thế giới JavaScript hiện đại. Nắm vững cách cấu hình request, hiểu rõ bản chất của Response object, và đặc biệt là xây dựng một kịch bản xử lý lỗi chặt chẽ sẽ giúp bạn viết ra những dòng code không chỉ chạy đúng, mà còn rất ổn định và chuyên nghiệp. Đừng ngại mở trình duyệt lên, bật tab Console và thử nghiệm ngay một vài API công khai vào dự án tiếp theo của mình nhé.
Bạn có “tuyệt chiêu” nào để tối ưu Fetch API hay một kỷ niệm “đau thương” nào khi vật lộn với lỗi CORS không? Chia sẻ ngay ở phần bình luận bên dưới để anh em cùng thảo luận nhé!
Lưu ý: Các thông tin trong bài viết này chỉ mang tính chất tham khảo. Để có được lời khuyên tốt nhất, vui lòng liên hệ trực tiếp với chúng tôi để được tư vấn cụ thể dựa trên nhu cầu thực tế của bạn.