1. Mục tiêu bài học
Sau bài học này, bạn sẽ hiểu cách JavaScript trao đổi dữ liệu với Laravel thông qua JSON và HTTP, nền tảng quan trọng để xây dựng ứng dụng Vue + Laravel REST API.
Bạn sẽ học được:
JSON là gì và tại sao frontend cần JSON?
Chuyển đổi dữ liệu giữa JSON và JavaScript.
HTTP Request và HTTP Response hoạt động như thế nào?
Các HTTP Method:
GET,POST,PUT,PATCH,DELETE.Các HTTP Status Code phổ biến.
Xử lý lỗi khi gọi API.
Thực hành gửi và nhận dữ liệu JSON bằng
fetch().Chuẩn bị cho Bài 08: JavaScript gọi Laravel REST API.
2. JSON là gì?
JSON (JavaScript Object Notation) là một định dạng văn bản dùng để lưu trữ và trao đổi dữ liệu giữa các hệ thống.
Ví dụ, Laravel có thể trả về thông tin một bài viết dưới dạng JSON:
{
"id": 1,
"title": "Học Laravel 13",
"author": "Nguyen Van A",
"published": true
}JavaScript nhận dữ liệu này, sau đó hiển thị tiêu đề, tác giả và trạng thái bài viết lên giao diện.
Laravel Backend
Lấy dữ liệu từ database
HTTP Request / Response — JSON
JavaScript Frontend
Nhận dữ liệu và cập nhật giao diện
Lưu ý: JSON là định dạng dữ liệu, còn HTTP là giao thức truyền dữ liệu. Hai khái niệm này thường được sử dụng cùng nhau khi xây dựng REST API.
3. JSON khác JavaScript Object như thế nào?
Hai dạng dữ liệu trông khá giống nhau nhưng không hoàn toàn giống nhau.
JavaScript Object
const post = {
id: 1,
title: "Học JavaScript",
published: true
};
console.log(post.title);Đây là một object mà JavaScript có thể sử dụng trực tiếp.
JSON String
const jsonString = `{
"id": 1,
"title": "Học JavaScript",
"published": true
}`;Đây là một chuỗi văn bản có nội dung theo cú pháp JSON.
Một số quy tắc quan trọng của JSON:
Tên thuộc tính phải đặt trong dấu ngoặc kép
" ".Chuỗi ký tự phải dùng dấu ngoặc kép.
Không cho phép comment trong JSON chuẩn.
Không hỗ trợ trực tiếp các giá trị
undefined,functionhoặcSymbol.
Ví dụ JSON không hợp lệ:
{
title: 'Laravel 13',
// Đây là bài viết mới
published: true
}Nguyên nhân: title không được đặt trong dấu ngoặc kép và JSON không hỗ trợ comment.
4. Chuyển đổi JSON và JavaScript
JavaScript cung cấp hai phương thức quan trọng: JSON.parse() và JSON.stringify().
4.1. JSON.parse() — Chuyển JSON thành Object
const jsonString = '{"id":1,"title":"Laravel 13"}';
const post = JSON.parse(jsonString);
console.log(post.id);
console.log(post.title);Kết quả:
1
Laravel 13Luồng chuyển đổi:
JSON String
Văn bản trao đổi dữ liệu
JSON.parse()
JavaScript Object
Truy cập bằng post.id, post.title
4.2. JSON.stringify() — Chuyển Object thành JSON String
const post = {
id: 1,
title: "Học Vue",
published: true
};
const jsonString = JSON.stringify(post);
console.log(jsonString);Kết quả:
{"id":1,"title":"Học Vue","published":true}Phương thức này thường được sử dụng khi gửi dữ liệu từ JavaScript lên Laravel.
Ví dụ:
const user = {
name: "Minh",
email: "minh@example.com"
};
const body = JSON.stringify(user);Biến body chứa chuỗi JSON sẵn sàng để gửi trong HTTP Request.
Ghi nhớ nhanh:
Phương thức | Chức năng |
|---|---|
| JSON String → JavaScript Object |
| JavaScript Object → JSON String |
5. HTTP là gì?(---)
HTTP là giao thức giúp client và server trao đổi dữ liệu.
Trong một ứng dụng Laravel, client có thể là trình duyệt chạy JavaScript hoặc Vue. Server là ứng dụng Laravel tiếp nhận yêu cầu và trả về kết quả.
Một HTTP Request thường có:
Method: Hành động muốn thực hiện.
URL: Địa chỉ tài nguyên.
Headers: Thông tin mô tả request.
Body: Dữ liệu gửi lên, nếu có.
Một HTTP Response thường có:
Status Code: Kết quả xử lý.
Headers: Thông tin phản hồi.
Body: Dữ liệu trả về, chẳng hạn JSON.
Ví dụ một request lấy danh sách bài viết:
GET /api/posts HTTP/1.1
Accept: application/jsonVí dụ response:
HTTP/1.1 200 OK
Content-Type: application/json[
{
"id": 1,
"title": "Bài viết đầu tiên"
},
{
"id": 2,
"title": "Bài viết thứ hai"
}
]Đây là cách frontend yêu cầu Laravel cung cấp danh sách bài viết.
6. Năm HTTP Method cần biết
Method | Ý nghĩa | Ví dụ |
|---|---|---|
| Lấy dữ liệu | Xem danh sách bài viết |
| Tạo tài nguyên mới | Thêm bài viết |
| Thay thế toàn bộ tài nguyên theo quy ước API | Cập nhật toàn bộ bài viết |
| Cập nhật một phần tài nguyên | Đổi tiêu đề bài viết |
| Xóa tài nguyên | Xóa bài viết |
Ví dụ các endpoint Laravel:
GET /api/posts
GET /api/posts/1
POST /api/posts
PUT /api/posts/1
PATCH /api/posts/1
DELETE /api/posts/1Các endpoint trên là ví dụ theo quy ước REST API. Bạn cần khai báo route tương ứng ở phía Laravel để chúng hoạt động.
7. HTTP Status Code phổ biến
Status Code giúp frontend biết request đã thành công hay gặp vấn đề.
Mã | Ý nghĩa | Tình huống |
|---|---|---|
| Thành công | Lấy dữ liệu thành công |
| Đã tạo | Thêm bài viết thành công |
| Thành công, không có nội dung trả về | Xóa bài viết thành công |
| Request không hợp lệ | Dữ liệu gửi không đúng yêu cầu |
| Chưa xác thực hợp lệ | Chưa đăng nhập hoặc thông tin xác thực không hợp lệ |
| Không có quyền | User không được phép xóa bài viết |
| Không tìm thấy | Bài viết không tồn tại |
| Dữ liệu không vượt qua xử lý hoặc validation | Laravel trả lỗi validation |
| Lỗi server | Lỗi phát sinh trong backend |
Một điểm rất quan trọng: fetch() thường không tự động reject Promise khi server trả về HTTP 404 hoặc 500. Bạn cần kiểm tra response.ok hoặc response.status.
8. Đọc JSON từ Fetch API
Ở Bài 06, bạn đã học fetch(). Bây giờ chúng ta kết hợp Fetch API với JSON.
async function getPosts() {
try {
const response = await fetch("/api/posts", {
headers: {
Accept: "application/json"
}
});
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const posts = await response.json();
console.log(posts);
} catch (error) {
console.error("Không thể tải bài viết:", error.message);
}
}
getPosts();Giải thích:
fetch()gửi HTTP Request đến/api/posts.awaitchờ server trả về Response.response.okkiểm tra status thuộc nhóm 200–299.response.json()đọc body và chuyển JSON thành dữ liệu JavaScript.try...catchxử lý lỗi mạng, lỗi đọc dữ liệu hoặc lỗi do chúng ta chủ động ném ra.
Lưu ý: response.json() là một thao tác bất đồng bộ và trả về Promise. Bạn thường phải dùng await response.json().
9. Gửi JSON từ JavaScript lên Laravel
Giả sử bạn muốn tạo một bài viết mới với tiêu đề và nội dung.
async function createPost() {
const postData = {
title: "Học Laravel 13",
content: "Bài học về JSON và HTTP"
};
try {
const response = await fetch("/api/posts", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(postData)
});
const data = await response.json();
if (!response.ok) {
console.error("API trả lỗi:", data);
return;
}
console.log("Đã tạo bài viết:", data);
} catch (error) {
console.error("Lỗi kết nối:", error.message);
}
}
createPost();Ba dòng cần nhớ nhất:
method: "POST"Cho server biết chúng ta đang gửi request tạo tài nguyên.
"Content-Type": "application/json"Cho server biết body được gửi lên có định dạng JSON.
body: JSON.stringify(postData)Chuyển JavaScript Object thành chuỗi JSON để gửi qua HTTP.
Phía Laravel vẫn cần khai báo route, kiểm tra dữ liệu, xác thực và lưu dữ liệu. Đoạn JavaScript này không tự tạo API backend.
10. Xử lý lỗi validation từ Laravel
Khi Laravel validation thất bại, API thường trả về HTTP 422 cùng dữ liệu lỗi, nếu request được xử lý theo cơ chế JSON.
Ví dụ response:
{
"message": "The title field is required.",
"errors": {
"title": [
"The title field is required."
]
}
}JavaScript có thể xử lý như sau:
async function createPost() {
const response = await fetch("/api/posts", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
title: "",
content: "Nội dung bài viết"
})
});
const data = await response.json();
if (response.status === 422) {
console.log("Lỗi tiêu đề:", data.errors?.title);
return;
}
if (!response.ok) {
console.error("Có lỗi xảy ra:", data.message);
return;
}
console.log("Tạo bài viết thành công:", data);
}Trong dự án thực tế, bạn nên bổ sung try...catch để xử lý lỗi mạng và trường hợp body không phải JSON hợp lệ.
Toán tử ?. là optional chaining, giúp truy cập thuộc tính an toàn khi thuộc tính trước nó có thể không tồn tại.
Ví dụ:
data.errors?.titleNếu data.errors không tồn tại, JavaScript trả về undefined thay vì phát sinh lỗi khi truy cập title.
11. Ví dụ thực hành hoàn chỉnh
Bây giờ chúng ta xây dựng một trang HTML nhỏ để tải danh sách bài viết từ API và hiển thị kết quả.
Ví dụ dưới đây sử dụng endpoint /api/posts. Endpoint cần tồn tại và trả về một mảng JSON có các thuộc tính id và title.
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Danh sách bài viết</title>
</head>
<body>
<h1>Danh sách bài viết</h1>
<button id="loadPosts">Tải bài viết</button>
<p id="message" role="status"></p>
<ul id="posts"></ul>
<script>
const button = document.querySelector("#loadPosts");
const postsElement = document.querySelector("#posts");
const messageElement = document.querySelector("#message");
button.addEventListener("click", async () => {
postsElement.replaceChildren();
messageElement.textContent = "Đang tải dữ liệu...";
try {
const response = await fetch("/api/posts", {
headers: {
Accept: "application/json"
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const posts = await response.json();
if (!Array.isArray(posts)) {
throw new Error("API không trả về danh sách hợp lệ.");
}
for (const post of posts) {
const item = document.createElement("li");
item.textContent = `${post.id}: ${post.title}`;
postsElement.appendChild(item);
}
messageElement.textContent =
`Đã tải ${posts.length} bài viết.`;
} catch (error) {
messageElement.textContent =
`Không thể tải dữ liệu: ${error.message}`;
}
});
</script>
</body>
</html>
Phân tích chương trình
querySelector()tìm các phần tử HTML.addEventListener()lắng nghe thao tác nhấn nút.fetch()gọi API.response.json()chuyển body JSON thành dữ liệu JavaScript.Array.isArray()kiểm tra dữ liệu có phải mảng hay không.createElement()vàappendChild()tạo danh sách bài viết.textContenthiển thị nội dung văn bản an toàn hơn so với đưa dữ liệu API trực tiếp vàoinnerHTML.
Nếu Laravel và frontend chạy trên các origin khác nhau, bạn cần cấu hình URL API chính xác và xử lý CORS phù hợp. Nếu sử dụng cookie để xác thực, cấu hình credentials và CSRF cũng sẽ cần được xem xét.
12. Bài tập thực hành
6 câu hỏi ôn tập
Bài 1: Chuyển JSON String thành JavaScript Object.
Xem đáp ánBài 2: Chuyển JavaScript Object thành JSON String.
Xem đáp ánBài 3: Lấy danh sách bài viết từ /api/posts.
Xem đáp ánBài 4: Gửi dữ liệu tạo bài viết bằng HTTP Method nào?
Xem đáp ánBài 5: Laravel trả status 422. Đây thường là lỗi gì?
Xem đáp ánBài 6: Vì sao phải kiểm tra response.ok?
Xem đáp án13. Tổng kết bài 07
Sau bài học này, bạn cần nắm chắc những kiến thức sau:
JSON dùng để trao đổi dữ liệu giữa frontend và backend.
JSON.parse()chuyển JSON String thành giá trị JavaScript.JSON.stringify()chuyển dữ liệu JavaScript thành JSON String.HTTP Method xác định loại thao tác với tài nguyên.
HTTP Status Code cho biết kết quả xử lý request.
fetch()kết hợpresponse.json()giúp nhận dữ liệu từ API.Khi gửi JSON, thường sử dụng
Content-Type: application/json.Luôn kiểm tra
response.okvà xử lý các lỗi có thể xảy ra.
14. Bài tiếp theo — Bài 08
JavaScript gọi Laravel REST API
Ở bài tiếp theo, chúng ta sẽ đưa các kiến thức JSON, HTTP, Promise, Async/Await và Fetch API vào một tình huống thực tế:
Kết nối JavaScript với Laravel 13.
Gọi API lấy danh sách bài viết.
Hiển thị dữ liệu Laravel trên trình duyệt.
Gửi dữ liệu tạo bài viết mới.
Xử lý lỗi validation và HTTP Response.
Hoàn thiện luồng giao tiếp frontend–backend trước khi chuyển sang Vue.
Đây là bước chuyển từ học JavaScript riêng lẻ sang xây dựng ứng dụng frontend thực sự.
Gợi ý: Hãy thử chạy bài thực hành với một endpoint /api/posts của Laravel trước khi sang Bài 08; bạn sẽ dễ hiểu cách Vue kết nối backend hơn.
✦ Made by AI ✦



Không có nhận xét nào:
Đăng nhận xét