JSON trong JavaScript: Hướng dẫn đọc, tạo và xử lý dữ liệu JSON
Bùi Tấn Lực
- 106
- 05/09/2026
Trong quá trình xây dựng website, JavaScript thường xuyên phải trao đổi dữ liệu với máy chủ, API hoặc các thành phần khác của hệ thống. Dữ liệu có thể được trả về dưới nhiều dạng, nhưng JSON đã trở thành một trong những định dạng phổ biến nhất nhờ cấu trúc rõ ràng, dễ đọc và đặc biệt phù hợp với cách JavaScript tổ chức dữ liệu.
Nếu hiểu JSON chỉ đơn giản là một chuỗi ký tự có dấu ngoặc nhọn thì khi bắt đầu làm việc với API, dữ liệu động hoặc hệ thống quản trị, bạn rất dễ gặp lỗi. Điều quan trọng không chỉ là biết cách viết một JSON hợp lệ mà còn phải hiểu sự khác nhau giữa JSON và object JavaScript, biết lúc nào cần chuyển đổi dữ liệu, cách kiểm tra dữ liệu trước khi sử dụng và cách xử lý trường hợp dữ liệu không đúng định dạng.
Bài viết này của Web Mới đi từ nền tảng đến thực tế, tập trung vào những thao tác thường gặp nhất khi xử lý JSON bằng JavaScript. Thay vì đưa ra hàng loạt đoạn mã rời rạc, nội dung sẽ giúp bạn hình thành một quy trình rõ ràng: nhận dữ liệu → đọc dữ liệu → chuyển đổi → xử lý → tạo dữ liệu → gửi dữ liệu.

JSON đóng vai trò gì trong JavaScript?
JSON là viết tắt của JavaScript Object Notation, một định dạng biểu diễn dữ liệu theo dạng văn bản. JSON được thiết kế để con người có thể đọc tương đối dễ dàng, đồng thời máy tính có thể phân tích và chuyển đổi thành dữ liệu để xử lý.
Điểm khiến JSON đặc biệt hữu ích trong JavaScript là cấu trúc của nó gần với object và array. Một dữ liệu JSON có thể mô tả thông tin của người dùng, sản phẩm, bài viết, đơn hàng, danh sách danh mục hoặc kết quả trả về từ một API.
Ví dụ, một hệ thống bán hàng có thể trả về thông tin sản phẩm như tên, giá, trạng thái và số lượng. Thay vì truyền từng giá trị riêng biệt, toàn bộ thông tin có thể được đóng gói thành một cấu trúc JSON có tổ chức.
{
"name": "Website doanh nghiệp",
"price": 5000000,
"status": true
}
Điều quan trọng cần nhớ là JSON bản chất là dữ liệu dạng văn bản theo một quy tắc nhất định. Khi JavaScript cần thao tác trực tiếp với dữ liệu đó, chúng ta thường phải chuyển JSON thành object hoặc array JavaScript.
JSON và object JavaScript không phải là một
Đây là điểm người mới học thường nhầm nhất. JSON và object JavaScript có hình thức khá giống nhau nhưng chúng không hoàn toàn giống nhau.
Object JavaScript là một kiểu dữ liệu mà chương trình có thể truy cập trực tiếp vào thuộc tính. Trong khi đó, JSON thường tồn tại dưới dạng chuỗi văn bản khi được truyền qua mạng, lưu trữ hoặc trao đổi giữa các hệ thống.
Ví dụ một object JavaScript có thể được viết như sau:
const sanPham = {
name: "Website doanh nghiệp",
price: 5000000,
status: true
};
Còn JSON tương ứng thường được biểu diễn dưới dạng chuỗi:
const jsonSanPham = '{"name":"Website doanh nghiệp","price":5000000,"status":true}';
Ở ví dụ đầu tiên, sanPham là object. Ở ví dụ thứ hai, jsonSanPham là một chuỗi chứa nội dung JSON.
Sự khác biệt này quyết định cách bạn xử lý dữ liệu. Nếu đang có object JavaScript và muốn biến nó thành JSON, bạn cần sử dụng JSON.stringify(). Ngược lại, nếu nhận được JSON dạng chuỗi và muốn thao tác như object JavaScript, bạn cần dùng JSON.parse().
Cấu trúc dữ liệu JSON cần nắm trước khi xử lý
JSON không phải là một ngôn ngữ lập trình. Nó là một quy tắc biểu diễn dữ liệu. Vì vậy, muốn xử lý tốt JSON trong JavaScript, trước tiên cần hiểu những kiểu dữ liệu mà JSON cho phép sử dụng.
Một cấu trúc JSON có thể bao gồm object, array, chuỗi, số, boolean và giá trị null. Những thành phần này có thể được kết hợp để tạo ra dữ liệu đơn giản hoặc những cấu trúc nhiều tầng.
Object trong JSON
Object JSON được bao quanh bởi dấu ngoặc nhọn { }. Bên trong object là các cặp key và value.
{
"name": "Web Mới",
"domain": "webmoi.vn",
"active": true
}
Trong đó, name, domain và active là các key. Giá trị tương ứng lần lượt là chuỗi, chuỗi và boolean.
Key trong JSON phải được đặt trong dấu ngoặc kép. Đây là một điểm khác biệt quan trọng so với cách viết object JavaScript.
Array trong JSON
Array được bao quanh bởi dấu ngoặc vuông [ ] và dùng để biểu diễn một danh sách dữ liệu.
[
"HTML",
"CSS",
"JavaScript",
"JSON"
]
Array cũng có thể chứa nhiều object, đây là dạng xuất hiện rất thường xuyên khi làm việc với API.
[
{
"id": 1,
"name": "Sản phẩm A"
},
{
"id": 2,
"name": "Sản phẩm B"
}
]
Khi nhận một danh sách sản phẩm từ API, dữ liệu thường có cấu trúc tương tự. JavaScript có thể duyệt qua từng phần tử của array để hiển thị hoặc xử lý.
Các kiểu giá trị được phép sử dụng
JSON hỗ trợ một số kiểu giá trị cơ bản:
- String: chuỗi ký tự nằm trong dấu ngoặc kép.
- Number: số nguyên hoặc số thập phân.
- Boolean: chỉ gồm true hoặc false.
- Object: tập hợp các cặp key và value.
- Array: danh sách các giá trị.
- null: biểu thị giá trị rỗng hoặc chưa có giá trị.
JSON không có kiểu undefined, không có function và cũng không thể biểu diễn trực tiếp các kiểu dữ liệu đặc biệt của JavaScript như Date theo cách riêng của JavaScript.
Đây là nguyên nhân khiến một số dữ liệu khi chuyển từ object JavaScript sang JSON có thể không còn giữ nguyên cách biểu diễn ban đầu.
Đọc dữ liệu JSON bằng JSON.parse()
Khi JSON tồn tại dưới dạng chuỗi, JavaScript chưa thể truy cập trực tiếp vào các thuộc tính bên trong như cách truy cập object. Lúc này, JSON.parse() được sử dụng để phân tích chuỗi JSON và chuyển nó thành dữ liệu JavaScript tương ứng.
Ví dụ:
const jsonData = '{"name":"Web Mới","domain":"webmoi.vn"}';
const data = JSON.parse(jsonData);
console.log(data.name);
console.log(data.domain);
Sau khi parse thành công, biến data trở thành một object JavaScript. Bạn có thể truy cập thuộc tính bằng dấu chấm hoặc dấu ngoặc vuông.
console.log(data.name);
console.log(data["domain"]);
Hai cách trên đều có thể lấy giá trị tương ứng. Cách dùng dấu chấm thường ngắn gọn và dễ đọc khi tên thuộc tính đã biết rõ.
Đọc JSON có cấu trúc nhiều tầng
Dữ liệu thực tế hiếm khi chỉ có một vài thuộc tính đơn giản. API có thể trả về object chứa object khác hoặc array chứa nhiều object.
const jsonData = `{
"website": {
"name": "Web Mới",
"domain": "webmoi.vn",
"services": [
{
"name": "Thiết kế website",
"active": true
},
{
"name": "Lập trình website",
"active": true
}
]
}
}`;
const data = JSON.parse(jsonData);
console.log(data.website.name);
console.log(data.website.services[0].name);
Cách đọc dữ liệu phụ thuộc hoàn toàn vào cấu trúc bên trong JSON. Với object lồng nhau, bạn đi qua từng thuộc tính. Với array, bạn truy cập phần tử bằng vị trí hoặc duyệt qua danh sách.
Đây cũng là lý do không nên chỉ nhìn vào một đoạn JSON rồi đoán cách truy cập. Trước khi viết JavaScript, hãy xác định rõ dữ liệu đang là object, array hay một cấu trúc kết hợp.
Xử lý JSON an toàn khi dữ liệu có thể bị lỗi
Một trong những lỗi phổ biến khi làm việc với JSON là gọi JSON.parse() trên một chuỗi không hợp lệ. Khi đó JavaScript có thể phát sinh lỗi và làm gián đoạn phần xử lý tiếp theo.
Ví dụ, chuỗi sau không phải JSON hợp lệ vì tên thuộc tính không được đặt trong dấu ngoặc kép:
const jsonData = "{name: 'Web Mới'}";
const data = JSON.parse(jsonData);
Nếu dữ liệu đến từ API, file hoặc nguồn bên ngoài, bạn không nên mặc định rằng dữ liệu luôn hoàn hảo. Một cách phổ biến là sử dụng try...catch để kiểm soát lỗi.
const jsonData = '{"name":"Web Mới"}';
try {
const data = JSON.parse(jsonData);
console.log(data.name);
} catch (error) {
console.log("Dữ liệu JSON không hợp lệ.");
}
Cách làm này đặc biệt hữu ích khi dữ liệu được lấy từ nguồn mà chương trình không hoàn toàn kiểm soát được. Thay vì để lỗi dừng toàn bộ quá trình, JavaScript có thể chuyển sang nhánh xử lý lỗi.
Khi nào nên kiểm tra dữ liệu sau khi parse?
JSON.parse() thành công không có nghĩa dữ liệu chắc chắn đúng với mục đích của ứng dụng. Đây là một khác biệt rất quan trọng.
Ví dụ JSON dưới đây hoàn toàn hợp lệ:
{
"name": 123,
"price": "không xác định"
}
Về mặt cú pháp, JSON này không sai. Nhưng nếu chương trình yêu cầu name phải là chuỗi và price phải là số thì dữ liệu vẫn không đáp ứng yêu cầu nghiệp vụ.
Vì vậy, quá trình xử lý dữ liệu nên được nhìn thành hai bước:
- Kiểm tra JSON có thể parse được hay không.
- Kiểm tra dữ liệu sau khi parse có đúng cấu trúc và kiểu giá trị mà ứng dụng cần hay không.
Việc phân biệt giữa lỗi cú pháp và lỗi dữ liệu giúp quá trình debug rõ ràng hơn và hạn chế những lỗi khó phát hiện khi website vận hành thực tế.
Tạo JSON từ dữ liệu JavaScript với JSON.stringify()
Nếu JSON.parse() dùng để đưa JSON về dữ liệu JavaScript thì JSON.stringify() thực hiện chiều ngược lại. Phương thức này chuyển object hoặc array JavaScript thành chuỗi JSON.
Ví dụ:
const sanPham = {
name: "Website doanh nghiệp",
price: 5000000,
active: true
};
const jsonData = JSON.stringify(sanPham);
console.log(jsonData);
Kết quả nhận được là một chuỗi JSON có thể dùng để lưu trữ hoặc gửi tới một máy chủ.
Điểm quan trọng là kết quả của JSON.stringify() là string, không còn là object JavaScript ban đầu.
Chuyển array JavaScript thành JSON
Không chỉ object, array cũng có thể được chuyển thành JSON.
const danhSach = [
{
id: 1,
name: "Sản phẩm A"
},
{
id: 2,
name: "Sản phẩm B"
}
];
const jsonData = JSON.stringify(danhSach);
console.log(jsonData);
Cách này thường được sử dụng khi một ứng dụng cần gửi danh sách dữ liệu đến máy chủ thông qua API.
Tạo JSON dễ đọc khi cần kiểm tra dữ liệu
JSON.stringify() còn hỗ trợ tham số thứ ba để định dạng chuỗi JSON với khoảng trắng. Điều này rất hữu ích khi cần kiểm tra dữ liệu trong quá trình phát triển.
const sanPham = {
name: "Website doanh nghiệp",
price: 5000000,
active: true
};
const jsonData = JSON.stringify(sanPham, null, 2);
console.log(jsonData);
Giá trị 2 yêu cầu JavaScript thụt vào hai khoảng trắng cho mỗi cấp dữ liệu. JSON lúc này dễ đọc hơn đáng kể so với chuỗi được nén thành một dòng.
Tuy nhiên, với dữ liệu cần truyền qua mạng, việc định dạng nhiều dòng không phải lúc nào cũng cần thiết. Khi đó, JSON dạng gọn thường phù hợp hơn vì giảm kích thước dữ liệu.
Đọc và tạo dữ liệu JSON theo một quy trình thống nhất
Khi mới học, nhiều người ghi nhớ riêng lẻ rằng parse là đọc và stringify là tạo. Cách nhớ này đúng nhưng chưa đủ để làm việc hiệu quả.
Trong một ứng dụng thực tế, bạn có thể hình dung luồng dữ liệu như sau:
- JavaScript tạo object hoặc array.
- Dữ liệu được chuyển thành chuỗi JSON khi cần truyền đi.
- Máy chủ nhận và xử lý dữ liệu.
- Máy chủ trả về JSON.
- JavaScript parse JSON thành object hoặc array.
- Ứng dụng kiểm tra và sử dụng dữ liệu.
Ví dụ, khi người dùng gửi thông tin một sản phẩm, JavaScript có thể tạo object trước:
const sanPham = {
name: "Website doanh nghiệp",
price: 5000000
};
Sau đó chuyển object thành JSON:
const jsonData = JSON.stringify(sanPham);
Khi nhận phản hồi JSON từ máy chủ, JavaScript lại đưa dữ liệu về object:
const data = JSON.parse(jsonData);
console.log(data.name);
Nhìn theo chu trình này, JSON không phải là nơi để JavaScript thao tác trực tiếp trong mọi trường hợp. JSON chủ yếu đóng vai trò cầu nối dữ liệu, còn object và array mới là những cấu trúc mà JavaScript thường sử dụng để xử lý trong chương trình.
Những lỗi thường gặp khi xử lý JSON
Phần lớn lỗi JSON trong JavaScript không đến từ những vấn đề quá phức tạp mà xuất phát từ việc nhầm lẫn giữa chuỗi JSON và dữ liệu JavaScript.
Gọi thuộc tính trước khi parse
Nếu dữ liệu vẫn là chuỗi JSON, bạn không thể xử lý nó như một object JavaScript.
const jsonData = '{"name":"Web Mới"}';
console.log(jsonData.name);
Trong trường hợp này, jsonData vẫn là string. Cần parse trước:
const data = JSON.parse(jsonData);
console.log(data.name);
Parse một object đã tồn tại
Ở chiều ngược lại, nếu bạn đã có object JavaScript thì không nên gọi JSON.parse() trực tiếp trên object đó.
const data = {
name: "Web Mới"
};
const result = JSON.parse(data);
JSON.parse() cần dữ liệu đầu vào là chuỗi JSON. Nếu mục tiêu là chuyển object thành JSON, phương thức phù hợp là JSON.stringify().
Quên xử lý trường hợp JSON không hợp lệ
Dữ liệu đến từ bên ngoài có thể chứa lỗi, bị cắt giữa chừng hoặc không đúng định dạng. Việc parse trực tiếp mà không có phương án xử lý lỗi có thể khiến một phần chức năng của website ngừng hoạt động.
Với các luồng dữ liệu quan trọng, nên xác định trước dữ liệu có thể đến từ đâu, trường hợp lỗi có thể xảy ra như thế nào và ứng dụng cần phản hồi ra sao khi dữ liệu không đáp ứng yêu cầu.
JSON trong JavaScript khi làm việc với dữ liệu website
Trong một website hiện đại, JSON thường xuất hiện ở nhiều vị trí khác nhau. Nó có thể nằm giữa frontend và backend, giữa website và API bên thứ ba, hoặc được dùng để lưu những cấu hình và dữ liệu trung gian.
Một website có thể sử dụng JSON để lấy danh sách sản phẩm, thông tin bài viết, dữ liệu tìm kiếm, thông tin người dùng hoặc kết quả của một thao tác trên hệ thống.
Điều quan trọng không phải là cố sử dụng JSON ở mọi nơi mà là nhận biết đúng thời điểm JSON phù hợp. Khi hai thành phần của hệ thống cần trao đổi dữ liệu có cấu trúc, JSON thường là một lựa chọn đơn giản và dễ triển khai.
Đối với người làm website, hiểu rõ JSON còn giúp việc đọc tài liệu API trở nên dễ dàng hơn. Khi nhìn thấy một response chứa object, array và các trường dữ liệu lồng nhau, bạn có thể xác định ngay cách JavaScript cần parse, truy cập và xử lý dữ liệu.
JSON nên được xem như một định dạng trao đổi dữ liệu, không phải một phiên bản khác của object JavaScript.
Nắm được nguyên tắc này sẽ giúp tránh rất nhiều nhầm lẫn khi chuyển dữ liệu giữa frontend, backend và API.
Duyệt và xử lý danh sách JSON trong JavaScript
Sau khi chuyển JSON thành object hoặc array bằng JSON.parse(), bước tiếp theo thường là lấy từng phần tử để xử lý. Với dữ liệu dạng danh sách, JavaScript cung cấp nhiều cách duyệt khác nhau. Việc lựa chọn cách nào phụ thuộc vào mục đích: chỉ đọc dữ liệu, tạo danh sách mới, tìm một phần tử hay lọc các phần tử thỏa điều kiện.
Giả sử một hệ thống trả về danh sách sản phẩm:
const jsonData = `[
{
"id": 1,
"name": "Website doanh nghiệp",
"price": 5000000,
"active": true
},
{
"id": 2,
"name": "Website bán hàng",
"price": 8000000,
"active": true
},
{
"id": 3,
"name": "Landing page",
"price": 3000000,
"active": false
}
]`;
const products = JSON.parse(jsonData);
Sau khi parse, products là một array. Bạn có thể sử dụng for...of để đi qua từng sản phẩm.
for (const product of products) {
console.log(product.name);
}
Cách này phù hợp khi cần thực hiện một thao tác tuần tự trên từng phần tử và muốn mã nguồn dễ đọc.
Dùng forEach() để xử lý từng phần tử
forEach() là lựa chọn quen thuộc khi mục tiêu chỉ đơn giản là duyệt qua toàn bộ danh sách.
products.forEach(function(product) {
console.log(product.name);
console.log(product.price);
});
Có thể viết ngắn gọn hơn bằng arrow function:
products.forEach(product => {
console.log(product.name);
});
Điểm cần nhớ là forEach() thích hợp cho việc thực hiện hành động trên từng phần tử, nhưng không phải lựa chọn tốt nhất nếu bạn muốn tạo ra một array mới hoặc cần tìm một phần tử cụ thể.
Lọc, tìm và biến đổi dữ liệu sau khi parse
Khi làm việc với JSON thực tế, việc đọc toàn bộ dữ liệu thường chỉ là bước đầu. Bạn có thể cần lọc sản phẩm đang hoạt động, tìm sản phẩm theo ID hoặc tạo một danh sách mới chỉ chứa những thông tin cần thiết.
Lọc dữ liệu với filter()
Ví dụ chỉ lấy những sản phẩm đang hoạt động:
const activeProducts = products.filter(product => {
return product.active === true;
});
console.log(activeProducts);
filter() không thay đổi trực tiếp array ban đầu. Nó tạo ra một array mới chứa những phần tử thỏa điều kiện.
Đây là cách rất phù hợp khi dữ liệu JSON chứa nhiều bản ghi nhưng giao diện chỉ cần hiển thị một nhóm nhất định.
Tìm một phần tử với find()
Nếu cần tìm sản phẩm có ID cụ thể, find() thường phù hợp hơn filter().
const product = products.find(product => {
return product.id === 2;
});
console.log(product);
Nếu tìm thấy, find() trả về phần tử đầu tiên thỏa điều kiện. Nếu không có phần tử phù hợp, kết quả là undefined.
Điều này cần được lưu ý khi hiển thị dữ liệu. Không nên mặc định rằng kết quả find() lúc nào cũng tồn tại.
Tạo dữ liệu mới với map()
Giả sử giao diện chỉ cần danh sách tên sản phẩm, bạn không nhất thiết phải giữ lại toàn bộ object.
const productNames = products.map(product => {
return product.name;
});
console.log(productNames);
Kết quả là một array mới chỉ chứa tên:
[
"Website doanh nghiệp",
"Website bán hàng",
"Landing page"
]
Trong những ứng dụng xử lý dữ liệu lớn, việc chỉ tạo ra cấu trúc mà giao diện thực sự cần có thể giúp mã nguồn rõ ràng hơn và giảm lượng dữ liệu phải truyền qua các bước xử lý tiếp theo.
Thêm, sửa và xóa dữ liệu trong cấu trúc JavaScript
JSON bản thân là định dạng văn bản nên bạn thường không thao tác trực tiếp lên chuỗi JSON để thêm hoặc xóa dữ liệu. Quy trình hợp lý là parse JSON → xử lý object hoặc array → stringify khi cần chuyển trở lại JSON.
Thêm một thuộc tính
Sau khi parse, bạn có thể thêm thuộc tính giống như khi làm việc với object JavaScript thông thường.
const jsonData = '{"name":"Website doanh nghiệp","price":5000000}';
const product = JSON.parse(jsonData);
product.active = true;
console.log(product);
Nếu cần biến dữ liệu đã thay đổi thành JSON một lần nữa:
const newJsonData = JSON.stringify(product);
console.log(newJsonData);
Cập nhật giá trị
Việc sửa dữ liệu cũng tương tự:
product.price = 6000000;
Với dữ liệu lồng nhau, cần truy cập đúng đường dẫn của thuộc tính.
const data = {
website: {
name: "Web Mới",
settings: {
language: "vi"
}
}
};
data.website.settings.language = "en";
Trước khi sửa một thuộc tính nằm sâu trong cấu trúc, cần chắc chắn rằng các object trung gian thực sự tồn tại. Đây là nguyên nhân phổ biến dẫn đến lỗi khi xử lý dữ liệu API không ổn định.
Xóa thuộc tính
JavaScript cho phép sử dụng delete để xóa thuộc tính khỏi object:
delete product.active;
Nếu dữ liệu sau đó được stringify, thuộc tính đã xóa sẽ không còn xuất hiện trong JSON kết quả.
Làm việc với JSON từ API bằng fetch()
Một trong những tình huống quan trọng nhất khi sử dụng JSON là lấy dữ liệu từ API. Trong trình duyệt hiện đại, fetch() thường được sử dụng để gửi HTTP request.
Ví dụ một API trả về JSON có thể được xử lý như sau:
fetch("/api/products")
.then(response => response.json())
.then(data => {
console.log(data);
})
.catch(error => {
console.error("Có lỗi xảy ra:", error);
});
Ở đây có một điểm rất dễ nhầm: response chưa phải object dữ liệu mà API trả về. Phương thức response.json() đọc nội dung response và chuyển dữ liệu JSON thành giá trị JavaScript.
Vì thao tác đọc body của response là bất đồng bộ, kết quả được xử lý thông qua Promise.
Viết request bằng async và await
Với các đoạn mã dài hơn, async/await thường giúp luồng xử lý dễ theo dõi hơn.
async function loadProducts() {
try {
const response = await fetch("/api/products");
if (!response.ok) {
throw new Error("API trả về lỗi.");
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
loadProducts();
Cách viết này tách rõ ba bước: gửi request, kiểm tra response và đọc JSON. Đây là cấu trúc dễ mở rộng khi ứng dụng cần thêm xử lý loading, thông báo lỗi hoặc cập nhật giao diện.
Không nên chỉ kiểm tra lỗi bằng catch()
Một hiểu lầm thường gặp là cho rằng mọi HTTP error đều tự động chạy vào catch(). Thực tế, fetch() có thể hoàn thành Promise ngay cả khi máy chủ trả về một mã HTTP lỗi như 404 hoặc 500.
Vì vậy, khi xử lý API, nên kiểm tra response.ok hoặc mã trạng thái HTTP trước khi đọc dữ liệu.
const response = await fetch("/api/products");
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
Cách kiểm tra này giúp phân biệt lỗi kết nối với lỗi do máy chủ phản hồi không thành công.
Gửi JSON từ JavaScript lên máy chủ
Không chỉ nhận dữ liệu, JavaScript còn thường phải gửi JSON đến backend. Khi đó, object JavaScript cần được chuyển thành chuỗi bằng JSON.stringify().
Ví dụ:
const product = {
name: "Website doanh nghiệp",
price: 5000000
};
fetch("/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(product)
});
Trong request này, Content-Type: application/json cho máy chủ biết nội dung body đang được gửi dưới dạng JSON.
Đây là chi tiết quan trọng. Nếu frontend gửi JSON nhưng không khai báo đúng Content-Type, backend có thể không xử lý body theo cách bạn mong muốn.
Gửi JSON và xử lý response
Trong thực tế, request thường cần chờ kết quả từ máy chủ:
async function createProduct() {
const product = {
name: "Website doanh nghiệp",
price: 5000000
};
try {
const response = await fetch("/api/products", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(product)
});
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
console.log("Dữ liệu máy chủ trả về:", data);
} catch (error) {
console.error("Không thể tạo sản phẩm:", error);
}
}
Quy trình này tạo thành một vòng trao đổi hoàn chỉnh: JavaScript tạo object, stringify thành JSON, gửi đến API, nhận response rồi chuyển response JSON thành dữ liệu JavaScript.
Xử lý JSON có dữ liệu thiếu hoặc không đúng cấu trúc
Không phải API nào cũng trả về dữ liệu hoàn hảo trong mọi trường hợp. Một thuộc tính có thể bị thiếu, có thể nhận giá trị null hoặc cấu trúc response có thể thay đổi theo trạng thái của request.
Ví dụ, nếu API không trả về user, đoạn mã sau có thể phát sinh lỗi:
console.log(data.user.name);
Có thể kiểm tra từng cấp trước khi truy cập:
if (data.user && data.user.name) {
console.log(data.user.name);
}
Trong JavaScript hiện đại, optional chaining giúp cách viết ngắn hơn:
console.log(data.user?.name);
Toán tử này đặc biệt hữu ích với dữ liệu JSON nhiều tầng vì cho phép dừng việc truy cập nếu một phần của cấu trúc không tồn tại.
Phân biệt null và dữ liệu không tồn tại
null và một thuộc tính hoàn toàn không tồn tại không phải là cùng một trường hợp.
Ví dụ:
const data = {
avatar: null
};
console.log(data.avatar);
console.log(data.email);
Ở đây, avatar tồn tại nhưng có giá trị null, trong khi email không tồn tại trong object.
Sự khác biệt này có thể ảnh hưởng đến logic hiển thị. Ví dụ, null có thể mang ý nghĩa rằng hệ thống biết trường đó tồn tại nhưng hiện chưa có dữ liệu, còn thuộc tính không tồn tại có thể cho thấy API không cung cấp trường đó.
JSON và dữ liệu biểu mẫu trên website
Khi người dùng nhập dữ liệu vào form, JavaScript thường lấy các giá trị từ input rồi tạo thành object trước khi gửi đến API.
Ví dụ:
const user = {
name: "Nguyễn Văn A",
email: "example@example.com"
};
const jsonData = JSON.stringify(user);
console.log(jsonData);
Cách tổ chức này giúp frontend có một cấu trúc dữ liệu rõ ràng trước khi gửi đi. Tuy nhiên, việc stringify không thay thế cho bước kiểm tra dữ liệu.
Ví dụ email không hợp lệ vẫn có thể được stringify thành JSON hoàn toàn bình thường. JSON chỉ đảm bảo dữ liệu tuân theo cú pháp JSON, chứ không đảm bảo dữ liệu đó đúng với quy tắc nghiệp vụ của website.
Do đó, một hệ thống tốt thường có ít nhất hai lớp kiểm tra: kiểm tra dữ liệu ở phía trình duyệt để cải thiện trải nghiệm và kiểm tra lại ở máy chủ để đảm bảo tính tin cậy.
Khi nào nên dùng JSON trong một ứng dụng JavaScript?
JSON đặc biệt phù hợp khi dữ liệu cần được trao đổi giữa các thành phần khác nhau. Ví dụ frontend JavaScript có thể giao tiếp với backend PHP, Node.js, Python hoặc một hệ thống khác thông qua API sử dụng JSON.
JSON cũng phù hợp với những dữ liệu có cấu trúc rõ ràng như:
- Danh sách sản phẩm.
- Thông tin khách hàng.
- Dữ liệu bài viết.
- Kết quả tìm kiếm.
- Thông tin đơn hàng.
- Cấu hình của một ứng dụng.
- Dữ liệu trao đổi giữa frontend và backend.
Tuy nhiên, không nên xem JSON là giải pháp lưu trữ cho mọi loại dữ liệu. Với hệ thống có dữ liệu quan hệ phức tạp, yêu cầu truy vấn lớn hoặc cần tính toàn vẹn dữ liệu cao, cơ sở dữ liệu chuyên dụng vẫn đóng vai trò quan trọng.
JSON phát huy hiệu quả nhất khi được sử dụng đúng vai trò: một định dạng dữ liệu trung gian rõ ràng, dễ trao đổi và dễ xử lý.
Quy trình xử lý JSON hiệu quả trong dự án thực tế
Khi dự án bắt đầu lớn hơn, việc chỉ biết parse và stringify là chưa đủ. Một quy trình xử lý dữ liệu tốt nên được tổ chức theo hướng kiểm soát được nguồn dữ liệu và các tình huống bất thường.
- Xác định cấu trúc dữ liệu: biết rõ object, array và các thuộc tính cần sử dụng.
- Nhận dữ liệu: lấy JSON từ API, file hoặc nguồn dữ liệu phù hợp.
- Kiểm tra response: xác định request có thành công hay không.
- Chuyển đổi: đưa JSON về object hoặc array JavaScript.
- Kiểm tra dữ liệu: xác định các trường bắt buộc và kiểu giá trị.
- Xử lý: lọc, tìm kiếm, cập nhật hoặc biến đổi dữ liệu.
- Hiển thị hoặc sử dụng: đưa dữ liệu vào giao diện hoặc logic ứng dụng.
- Chuyển ngược sang JSON: stringify khi cần gửi dữ liệu đi.
Điểm quan trọng nhất là không nên gộp tất cả các bước vào một đoạn mã dài. Khi tách rõ quá trình nhận, kiểm tra, xử lý và gửi dữ liệu, việc tìm lỗi và bảo trì website sẽ dễ dàng hơn rất nhiều.
Một đoạn JSON hợp lệ chỉ nói rằng dữ liệu đúng cú pháp; nó không đảm bảo dữ liệu đúng với yêu cầu của ứng dụng.
Đây là nguyên tắc nên ghi nhớ khi bắt đầu xây dựng các chức năng sử dụng API.
Chuyển đổi dữ liệu JSON theo đúng mục đích sử dụng
Trong một ứng dụng JavaScript, cùng một dữ liệu có thể phải đi qua nhiều trạng thái khác nhau. Ban đầu dữ liệu có thể là object, sau đó được chuyển thành JSON để gửi đến máy chủ, rồi lại được chuyển về object khi nhận response. Hiểu rõ thời điểm chuyển đổi sẽ giúp tránh được nhiều lỗi không đáng có.
Nguyên tắc đơn giản là object và array dành cho việc xử lý trong JavaScript, còn JSON thường được dùng khi dữ liệu cần biểu diễn dưới dạng văn bản để trao đổi hoặc lưu trữ.
const user = {
name: "Nguyễn Văn A",
role: "admin"
};
const jsonData = JSON.stringify(user);
const data = JSON.parse(jsonData);
console.log(data.name);
Không nên stringify dữ liệu nhiều lần nếu không có lý do cụ thể. Tương tự, cũng không nên parse một dữ liệu đã là object chỉ vì muốn chắc chắn rằng nó "là JSON". Việc xác định kiểu dữ liệu trước khi xử lý sẽ giúp code chính xác và dễ bảo trì hơn.
Kiểm tra kiểu dữ liệu trước khi xử lý
JavaScript cung cấp typeof để kiểm tra kiểu dữ liệu cơ bản.
const data = '{"name":"Web Mới"}';
console.log(typeof data);
Kết quả là string. Sau khi parse:
const objectData = JSON.parse(data);
console.log(typeof objectData);
Kết quả lúc này là object.
Việc kiểm tra kiểu dữ liệu đặc biệt hữu ích khi một hàm có thể nhận dữ liệu từ nhiều nguồn khác nhau. Thay vì giả định đầu vào luôn là JSON string, chương trình có thể xác định dữ liệu đang ở trạng thái nào trước khi thực hiện chuyển đổi.
Sao chép object chứa dữ liệu JSON đúng cách
Một tình huống khác thường xuất hiện khi xử lý dữ liệu là cần tạo một bản sao của object trước khi thay đổi. Nếu dữ liệu chỉ có một cấp đơn giản, việc sao chép tương đối dễ dàng. Nhưng với object lồng nhau, cách sao chép cần được lựa chọn cẩn thận.
Ví dụ:
const product = {
name: "Website doanh nghiệp",
price: 5000000,
settings: {
active: true
}
};
Nếu chỉ gán:
const copy = product;
thì copy và product vẫn tham chiếu đến cùng một object. Thay đổi dữ liệu trong copy có thể ảnh hưởng đến product.
Với dữ liệu JSON đơn giản, một cách phổ biến để tạo bản sao sâu là chuyển đổi qua JSON:
const copy = JSON.parse(JSON.stringify(product));
copy.settings.active = false;
console.log(product.settings.active);
console.log(copy.settings.active);
Cách này có thể hữu ích trong những trường hợp dữ liệu chỉ chứa các kiểu mà JSON biểu diễn tốt. Tuy nhiên, đây không phải kỹ thuật sao chép sâu phù hợp cho mọi object JavaScript.
Các giá trị đặc biệt như function, undefined hoặc một số kiểu dữ liệu JavaScript khác có thể không được giữ nguyên khi đi qua quá trình stringify rồi parse. Vì vậy, không nên sử dụng kỹ thuật này một cách máy móc cho mọi trường hợp.
Lưu JSON trong localStorage của trình duyệt
localStorage chỉ lưu dữ liệu dưới dạng chuỗi. Vì vậy, nếu muốn lưu object hoặc array, JSON.stringify() thường được sử dụng để chuyển dữ liệu thành chuỗi trước khi lưu.
const settings = {
language: "vi",
theme: "light"
};
localStorage.setItem(
"settings",
JSON.stringify(settings)
);
Khi lấy dữ liệu trở lại:
const storedData = localStorage.getItem("settings");
if (storedData) {
const settings = JSON.parse(storedData);
console.log(settings.language);
}
Đây là một ứng dụng rất thực tế của JSON trong trình duyệt. Các thiết lập nhỏ như lựa chọn giao diện, bộ lọc tìm kiếm hoặc trạng thái một số thành phần có thể được lưu dưới dạng JSON.
Không nên xem localStorage như cơ sở dữ liệu
Dù có thể lưu object bằng JSON, localStorage không phải là giải pháp thay thế cho cơ sở dữ liệu phía máy chủ.
Dữ liệu trong localStorage nằm ở trình duyệt của người dùng và có thể bị xóa hoặc thay đổi. Vì vậy, không nên lưu các thông tin quan trọng mà hệ thống cần bảo vệ tuyệt đối hoặc dùng dữ liệu này làm nguồn xác thực đáng tin cậy.
Đặc biệt, không nên lưu thông tin nhạy cảm vào localStorage chỉ vì dữ liệu đã được chuyển thành JSON. Việc stringify không làm dữ liệu trở nên an toàn hơn.
JSON và vấn đề dữ liệu nhạy cảm
JSON chỉ là định dạng dữ liệu. Nó không cung cấp cơ chế mã hóa hay bảo vệ dữ liệu.
Ví dụ:
const user = {
username: "admin",
password: "123456"
};
const jsonData = JSON.stringify(user);
Việc biến object thành JSON không khiến password trở nên an toàn. Nếu dữ liệu được gửi qua một kết nối không an toàn hoặc lưu tại nơi người dùng có thể truy cập, thông tin vẫn có nguy cơ bị lộ.
Trong website thực tế, dữ liệu nhạy cảm cần được bảo vệ bằng các cơ chế phù hợp ở tầng truyền tải, máy chủ, xác thực và lưu trữ. JSON chỉ đảm nhiệm việc biểu diễn dữ liệu.
Không đưa dữ liệu bí mật vào response nếu không cần thiết
Một nguyên tắc quan trọng khi thiết kế API là chỉ trả về những dữ liệu frontend thực sự cần.
Ví dụ, nếu giao diện chỉ cần tên và email, API không nên trả về thêm những trường nội bộ không phục vụ giao diện.
{
"name": "Nguyễn Văn A",
"email": "example@example.com"
}
Giảm dữ liệu không cần thiết vừa giúp response gọn hơn vừa hạn chế nguy cơ vô tình để lộ thông tin nội bộ.
Xử lý JSON lớn và vấn đề hiệu suất
JSON rất tiện lợi nhưng không có nghĩa là kích thước dữ liệu càng lớn thì hiệu quả vẫn như nhau. Khi một response chứa hàng chục nghìn hoặc hàng trăm nghìn bản ghi, quá trình tải, parse và xử lý đều có thể ảnh hưởng đến hiệu suất website.
Với dữ liệu lớn, vấn đề cần quan tâm không chỉ là thời gian truyền tải mà còn là lượng bộ nhớ JavaScript phải sử dụng.
Ví dụ, nếu API trả về toàn bộ hàng chục nghìn sản phẩm chỉ để giao diện hiển thị 20 sản phẩm đầu tiên, cách thiết kế đó rõ ràng chưa tối ưu.
Phân trang dữ liệu thay vì tải tất cả
API có thể chia dữ liệu thành từng trang:
{
"items": [
{
"id": 1,
"name": "Sản phẩm A"
},
{
"id": 2,
"name": "Sản phẩm B"
}
],
"page": 1,
"limit": 20,
"total": 250
}
Frontend chỉ nhận lượng dữ liệu cần thiết cho trang hiện tại. Khi người dùng chuyển trang, ứng dụng mới yêu cầu dữ liệu tiếp theo.
Cách tổ chức này đặc biệt phù hợp với website thương mại điện tử, trang quản trị, hệ thống tìm kiếm và những ứng dụng có số lượng bản ghi lớn.
Thiết kế cấu trúc JSON dễ sử dụng trong API
Một JSON tốt không chỉ cần hợp lệ mà còn cần dễ hiểu và nhất quán. Khi nhiều frontend hoặc nhiều hệ thống cùng sử dụng một API, cấu trúc dữ liệu càng rõ ràng thì việc tích hợp càng thuận lợi.
Ví dụ response danh sách sản phẩm có thể tổ chức thành:
{
"success": true,
"data": [
{
"id": 1,
"name": "Website doanh nghiệp",
"price": 5000000
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1
}
}
Cách tổ chức này giúp frontend dễ xác định phần nào là dữ liệu chính và phần nào là thông tin bổ sung.
Thống nhất tên thuộc tính
Một API nên có quy tắc đặt tên nhất quán. Không nên lúc dùng product_name, lúc lại dùng productName cho cùng một ý nghĩa nếu không có lý do kỹ thuật rõ ràng.
Sự nhất quán giúp frontend giảm logic chuyển đổi và làm tài liệu API dễ hiểu hơn.
Tương tự, kiểu dữ liệu cũng nên ổn định. Nếu trường price được xác định là number thì không nên lúc trả về number, lúc trả về string chỉ vì dữ liệu được lấy từ các nguồn khác nhau.
Xử lý giá trị ngày tháng trong JSON
JSON không có kiểu dữ liệu Date riêng. Vì vậy, ngày tháng thường được biểu diễn dưới dạng chuỗi.
{
"createdAt": "2026-09-05T10:30:00Z"
}
Sau khi parse, giá trị createdAt vẫn là string. Nếu JavaScript cần thực hiện các phép xử lý liên quan đến ngày tháng, bạn có thể chuyển chuỗi này thành đối tượng Date.
const data = {
createdAt: "2026-09-05T10:30:00Z"
};
const date = new Date(data.createdAt);
console.log(date);
Điều quan trọng là backend và frontend cần thống nhất cách biểu diễn ngày tháng. Nếu mỗi hệ thống sử dụng một định dạng khác nhau, việc xử lý múi giờ và hiển thị thời gian có thể trở nên phức tạp.
Chuyển JSON thành HTML để hiển thị dữ liệu
Một ứng dụng JavaScript thường lấy dữ liệu JSON rồi sử dụng dữ liệu đó để tạo giao diện. Ví dụ danh sách sản phẩm có thể được chuyển thành các phần tử HTML.
const products = [
{
name: "Website doanh nghiệp",
price: 5000000
},
{
name: "Website bán hàng",
price: 8000000
}
];
const html = products.map(product => {
return `
<p>
<strong>${product.name}</strong> -
${product.price} VNĐ
</p>
`;
}).join("");
console.log(html);
Khi đưa dữ liệu JSON vào giao diện, cần đặc biệt chú ý đến dữ liệu do người dùng hoặc nguồn bên ngoài cung cấp. Không nên đưa nội dung chưa được kiểm soát trực tiếp vào HTML theo cách có thể tạo ra lỗ hổng XSS.
JSON hợp lệ không đồng nghĩa với dữ liệu an toàn để chèn trực tiếp vào giao diện. Đây là hai vấn đề hoàn toàn khác nhau.
JSON không thay thế cho việc kiểm tra dữ liệu
Một trong những sai lầm lớn nhất khi làm việc với JSON là coi việc parse thành công như một dấu hiệu rằng dữ liệu đã đáng tin cậy.
Ví dụ:
const jsonData = `{
"price": "abc",
"quantity": -100
}`;
const data = JSON.parse(jsonData);
JSON trên hoàn toàn hợp lệ về mặt cú pháp. Tuy nhiên, price có thể cần là số và quantity không nên là số âm trong logic của một hệ thống bán hàng.
Vì vậy, sau bước parse cần có bước xác thực dữ liệu theo yêu cầu của ứng dụng.
Kiểm tra các trường bắt buộc
Ví dụ đơn giản:
if (
typeof data.price !== "number" ||
typeof data.quantity !== "number"
) {
throw new Error("Dữ liệu sản phẩm không hợp lệ.");
}
Với những ứng dụng lớn, việc xác thực có thể được tổ chức thành các hàm hoặc thư viện chuyên dụng để tránh lặp lại logic ở nhiều nơi.
Điều này đặc biệt quan trọng với dữ liệu nhận từ API bên ngoài, bởi frontend không nên giả định rằng response luôn có đúng cấu trúc như tài liệu mô tả.
Cách tổ chức code JSON dễ bảo trì hơn
Khi dự án nhỏ, việc parse hoặc stringify trực tiếp trong từng đoạn code có thể chưa gây ra vấn đề. Nhưng khi số lượng API tăng lên, cách làm này dễ dẫn đến tình trạng xử lý dữ liệu bị phân tán khắp ứng dụng.
Một cách tốt hơn là gom các thao tác liên quan đến API và chuyển đổi dữ liệu vào những hàm có trách nhiệm rõ ràng.
async function getProducts() {
const response = await fetch("/api/products");
if (!response.ok) {
throw new Error("Không thể lấy danh sách sản phẩm.");
}
return response.json();
}
async function loadProducts() {
try {
const products = await getProducts();
console.log(products);
} catch (error) {
console.error(error);
}
}
Ở đây, hàm getProducts() chịu trách nhiệm lấy dữ liệu, còn loadProducts() quyết định ứng dụng sẽ sử dụng dữ liệu đó như thế nào.
Khi cấu trúc ứng dụng phát triển, cách phân tách trách nhiệm này giúp việc thay đổi API hoặc xử lý lỗi dễ dàng hơn.
Những nguyên tắc quan trọng khi làm việc với JSON
Không cần ghi nhớ hàng chục quy tắc riêng lẻ. Chỉ cần nắm chắc một số nguyên tắc cốt lõi, bạn đã có thể xử lý phần lớn tình huống JSON thường gặp trong JavaScript.
- Phân biệt JSON string với object JavaScript.
- Dùng JSON.parse() khi cần chuyển JSON string thành dữ liệu JavaScript.
- Dùng JSON.stringify() khi cần chuyển object hoặc array thành JSON string.
- Không xem parse thành công là dữ liệu đã hợp lệ về mặt nghiệp vụ.
- Kiểm tra response HTTP trước khi xử lý dữ liệu API.
- Kiểm tra các trường có thể thiếu hoặc nhận giá trị null.
- Không lưu dữ liệu nhạy cảm ở nơi không phù hợp chỉ vì nó đã được chuyển thành JSON.
- Không tải một lượng JSON khổng lồ nếu giao diện chỉ cần một phần nhỏ dữ liệu.
- Giữ cấu trúc và kiểu dữ liệu API nhất quán.
- Tách phần lấy dữ liệu, kiểm tra dữ liệu và xử lý giao diện khi dự án lớn.
Từ JSON cơ bản đến xây dựng ứng dụng thực tế
JSON không khó ở bản thân cú pháp. Phần quan trọng hơn nằm ở cách dữ liệu được đưa qua các thành phần của một ứng dụng.
Khi mới học, chỉ cần hiểu rõ hai phương thức JSON.parse() và JSON.stringify() là bạn đã có nền tảng để bắt đầu. Sau đó, kiến thức cần mở rộng dần sang cách duyệt array, xử lý object lồng nhau, làm việc với fetch(), kiểm tra response, xác thực dữ liệu và tối ưu API.
Trong một website thực tế, JSON thường không đứng độc lập. Nó kết nối giao diện với backend, kết nối các dịch vụ với nhau và giúp những hệ thống được viết bằng công nghệ khác nhau có thể trao đổi dữ liệu theo một cấu trúc thống nhất.
Đó cũng là lý do việc hiểu đúng JSON có giá trị lớn hơn việc chỉ học thuộc cú pháp. Khi bạn biết dữ liệu đang ở dạng nào, dữ liệu đến từ đâu, cần chuyển đổi ở bước nào và phải kiểm tra điều gì trước khi sử dụng, việc xây dựng các chức năng JavaScript sẽ trở nên chủ động và ít lỗi hơn.
Với những người đang phát triển website, Web Mới khuyến nghị nên học JSON song song với JavaScript và API thay vì xem JSON như một chủ đề tách biệt. Khi ba phần này được hiểu như một chuỗi xử lý dữ liệu hoàn chỉnh, bạn sẽ dễ dàng đọc response, xây dựng request và kết nối frontend với backend hơn rất nhiều.
Hiểu JSON không chỉ là biết đọc dấu ngoặc nhọn. Điều quan trọng là biết dữ liệu được tạo ra ở đâu, được chuyển đổi như thế nào và cần được kiểm tra ra sao trước khi ứng dụng sử dụng nó.
Đó chính là nền tảng để từ những đoạn JavaScript đơn giản phát triển thành các chức năng sử dụng API và hệ thống web có dữ liệu động một cách ổn định.
- 0 Bình luận
Email, Điện thoại của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *