📚 EVEDAYS Guide Book
[Công cụ lập trình]•6 phút đọc

Năm lý do JSON bị lỗi khi phân tích cú pháp và cái bẫy số lớn

1. JSON chặt chẽ hơn vẻ ngoài


JSON trông giống literal đối tượng của JavaScript nhưng cho phép ít hơn nhiều. JSON được định nghĩa bởi RFC 8259 và ECMA-404, và rất nhiều thứ hợp lệ trong JavaScript lại không hợp lệ trong JSON.

2. Năm lý do phân tích cú pháp thất bại


① Dấu phẩy thừa ở cuối
{"a": 1, "b": 2,} — dấu phẩy sau phần tử cuối cùng là lỗi. JavaScript cho phép; JSON thì không.

② Khóa không có dấu ngoặc kép
{a: 1} — khóa phải là chuỗi đặt trong dấu ngoặc kép.

③ Dấu nháy đơn
{'a': 'b'} — JSON chỉ chấp nhận dấu ngoặc kép.

④ Chú thích
Cả // ghi chú lẫn /* */ đều không tồn tại trong JSON chuẩn. Các tệp cấu hình cần chú thích phải dùng phần mở rộng như JSONC hoặc JSON5.

⑤ Giá trị đặc biệt
NaN, Infinity và undefined không phải là JSON. Hãy biểu diễn số bị thiếu bằng null hoặc bằng chuỗi.

Một lỗi phổ biến khác là ký tự xuống dòng thô nằm trong chuỗi; nó phải được thoát thành \n.

3. Đọc vị trí báo lỗi


Trình phân tích thường báo kiểu như "position 42", nhưng nguyên nhân thật thường nằm ở phía trước. Chỉ cần thiếu một dấu ngoặc kép, trình phân tích sẽ nuốt phần còn lại của tài liệu như một phần của chuỗi cho đến khi báo lỗi ở rất xa phía sau.

Chạy tài liệu qua công cụ định dạng để bung cấu trúc ra sẽ giúp dễ dàng phát hiện chỗ lồng nhau bị lệch.

4. Cái bẫy số lớn


Đây không phải lỗi cú pháp mà là giá trị bị thay đổi âm thầm, nên càng nguy hiểm hơn.

Số trong JavaScript là số thực dấu phẩy động độ chính xác kép, vì vậy số nguyên chỉ được biểu diễn chính xác đến:

Number.MAX_SAFE_INTEGER = 9007199254740991

Phân tích một số nguyên lớn hơn bằng JSON.parse sẽ âm thầm làm thay đổi nó. Ví dụ 12345678901234567890 trở thành 12345678901234567000, không có lỗi cũng không có cảnh báo.

Khi nào bạn gặp phải
  • ID 64-bit kiểu Snowflake (Twitter, Discord và tương tự)

  • Khóa chính BIGINT từ cơ sở dữ liệu

  • Số tiền lớn được biểu diễn theo đơn vị nhỏ nhất


  • Cách khắc phục
    Giải pháp chuẩn là để máy chủ tuần tự hóa các giá trị đó thành chuỗi: {"id": "12345678901234567890"}. Nếu phía client buộc phải xử lý chúng như số, hãy dùng BigInt cùng một hàm reviver tùy chỉnh.

    5. Các biến thể của JSON


    | Định dạng | Khác biệt | Dùng cho |
    |---|---|---|
    | JSON | Chuẩn | Phản hồi API, trao đổi dữ liệu |
    | JSONC | Cho phép chú thích | Cài đặt VS Code và tương tự |
    | JSON5 | Chú thích, dấu phẩy cuối, dấu nháy đơn | Tệp cấu hình viết tay |
    | NDJSON / JSON Lines | Mỗi dòng một giá trị JSON | Log, streaming, xử lý hàng loạt |

    Đừng trả về JSONC từ API chỉ vì nó chạy được trong tệp cấu hình; các trình phân tích chuẩn sẽ từ chối nó.

    6. Lưu ý bảo mật


    Thỉnh thoảng vẫn gặp mã đưa chuỗi JSON vào eval(). Đừng bao giờ làm vậy. Dữ liệu đầu vào không đáng tin chứa mã sẽ bị thực thi như mã. JSON.parse thì an toàn.

    7. Công cụ


    Công cụ định dạng JSON EVEDAYS kiểm tra và định dạng ngay trong trình duyệt của bạn. Phản hồi API thường chứa dữ liệu cá nhân hoặc token, nên công cụ không bao giờ truyền chúng đi là lựa chọn an toàn hơn.

    8. Nguồn


  • RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format

  • ECMA-404 — The JSON Data Interchange Syntax

  • MDN — JSON.parse()
  • EVEDAYS Editorial Team