Vì sao dấu phẩy cuối làm hỏng JSON
Kết luận: Dấu phẩy cuối hợp lệ trong object literal của JavaScript nhưng lại gây lỗi chí mạng trong JSON. Đây là thông báo lỗi chính xác, ngữ pháp RFC 8259 gây ra nó, và ba cách sửa thực sự hiệu quả.

Tóm lại: JSON cấm dấu phẩy cuối ở mọi nơi — khi bộ phân tích thất bại, hãy xóa dấu phẩy cuối cùng bằng công cụ định dạng; chỉ dùng JSON5 hoặc JSONC cho việc phân tích dễ dãi cục bộ, và luôn gửi JSON chuẩn cho các hệ thống khác.
Vì ngữ pháp quy định như vậy.
{
"name": "demo",
"size": 12,
}
JSON.parse ném Unexpected token } in JSON at position 34. Node diễn đạt khác đi, nhưng mọi engine đều chỉ vào cùng một chỗ: dấu phẩy trước }.
Bộ phân tích thực sự phàn nàn điều gì
Luật sinh đối tượng trong RFC 8259 là:
object = begin-object [ member *( value-separator member ) ] end-object
Dấu ngoặc vuông nghĩa là tùy chọn, dấu hoa thị nghĩa là không hoặc nhiều. Nói đơn giản: dấu phẩy phân tách các thành viên, và thành viên cuối cùng được theo ngay bởi }.
Vậy sau một dấu phẩy, bộ phân tích sẵn sàng cho tên thành viên tiếp theo. Nó đọc } và thất bại. Mảng cũng hành xử y hệt — [1, 2, 3,] thất bại tại ].
Thói quen này đến từ đâu
Object literal của JavaScript đã cho phép dấu phẩy cuối từ ES5, danh sách của Python và composite literal của Go cũng vậy. Trình soạn thảo tự thêm chúng. Rồi ai đó sao chép một object literal từ tệp .js sang tệp .json và tệp ngừng phân tích được.
Nguồn phổ biến khác là JSON dựng thủ công: một vòng lặp chạy i <= length để lại dấu phẩy sau phần tử cuối.
Ba cách sửa
Xóa dấu phẩy. Ổn với chỉnh sửa thủ công. Hãy dán vào công cụ định dạng JSON và lỗi sẽ được báo kèm dòng cùng cột, để bạn thấy chính xác dấu nào cần xóa.
Phân tích dưới dạng JSON5. Các siêu ngôn ngữ chấp nhận dấu phẩy cuối, phù hợp cho cấu hình cục bộ. Không phù hợp cho bất cứ thứ gì bạn gửi cho hệ thống khác — bên nhận vẫn sẽ từ chối.
Đừng nối chuỗi nữa. Hãy dùng JSON.stringify, json.dumps, Jackson. Serializer xử lý dấu phân cách đúng và đồng thời giải quyết luôn việc escape.
Danh sách rà soát nhanh
| Nơi | Nguyên nhân thường gặp |
|---|---|
| Nối chuỗi trong vòng lặp | i <= length để lại một dấu phẩy thừa |
| Sao chép - dán | Object literal lấy từ tệp JS |
| Template | Dấu phẩy viết cứng cộng với vòng lặp thêm một dấu nữa |
| Chỉnh sửa thủ công | Trường cuối bị xóa, dấu phẩy của nó bị bỏ lại |
Câu hỏi thường gặp
Vì sao dấu phẩy cuối hợp lệ trong JavaScript nhưng không trong JSON?
Object literal của JavaScript đã cho phép chúng từ ES5, danh sách Python và composite literal Go cũng vậy, nên thói quen theo người ta vào JSON. RFC 8259 chỉ cho phép dấu phẩy giữa các thành viên: thành viên cuối được theo ngay bởi } hoặc ]. Việc sao chép object literal từ tệp .js sang tệp .json là nguồn thường gặp.
Tôi có nên phân tích dưới dạng JSON5 để chấp nhận dấu phẩy cuối không?
Chỉ cho cấu hình cục bộ. Các siêu ngôn ngữ chấp nhận dấu phẩy cuối, nhưng bất cứ thứ gì bạn gửi cho hệ thống khác đều được phân tích như JSON nghiêm ngặt và vẫn sẽ thất bại. Hãy sinh JSON chuẩn ở ranh giới đầu ra thay vì trông chờ bên nhận dễ dãi.
Sau lỗi dấu phẩy cuối nên tìm ở đâu trước?
Bắt đầu với vị trí trong thông báo lỗi: nó thường chỉ vào dấu phẩy trước } hoặc ]. Sau đó kiểm tra ba nguồn quen thuộc: một vòng lặp viết với i <= length, một object literal dán từ tệp JS, và một template viết cứng dấu phẩy bên cạnh vòng lặp. Dán vào công cụ định dạng sẽ báo chính xác dòng và cột.