Tiếng Việt

Công cụ dành cho nhà phát triển · JSON trình định dạng và xác thực

JavaScript đối tượng bằng chữ so với JSON: tại sao dấu ngoặc đơn không xác thực được

· Cách thức hoạt động

json developer-workflow xác nhận

JavaScript đối tượng bằng chữ so với JSON: tại sao dấu nháy đơn không xác thực được minh họa bằng mã thông báo JSON và ranh giới xác thực chính xác
Hình minh họa vector ToolAcre gốc

Một đối tượng được in bởi bảng điều khiển JavaScript trông giống như JSON nhưng thường thì không phải vậy. Bài đăng này liệt kê những khác biệt chính xác (dấu ngoặc kép, khóa không trích dẫn, không xác định, hàm) và hiển thị vị trí mỗi điểm đi qua trình xác thực.

Nó ra khỏi bảng điều khiển, vậy tại sao nó không hợp lệ?

Nó ra khỏi bảng điều khiển, vậy tại sao nó không hợp lệ? — bảng điều khiển dành cho nhà phát triển hiển thị các giá trị JavaScript dưới dạng văn bản giống nguồn JavaScript chứ không phải dưới dạng tuần tự hóa JSON được đảm bảo. Đối tượng được sao chép có thể chứa tên thuộc tính đơn giản, chuỗi trích dẫn đơn, `undefined` hoặc chú thích dành riêng cho trình duyệt. Tất cả những điều đó đều có thể hiểu được đối với công cụ JavaScript hoặc trình đọc của con người nhưng lại bị lỗi ngay lập tức trong tệp `.json`, có ngữ pháp nhỏ hơn một cách có chủ ý và không phụ thuộc vào mã thực thi.

Hãy xem xét `{name: "Ada", active: true, missing: undefined}`. Các dấu ngoặc nhọn, dấu hai chấm và boolean giống JSON nhưng khóa trống đầu tiên đã vi phạm quy tắc thành viên đối tượng và `undefined` sẽ không thành công sau đó. ToolAcre báo cáo ký tự hoặc giá trị không được hỗ trợ đầu tiên bằng một dòng và cột, vì vậy tốt nhất nên thực hiện chuyển đổi theo thứ tự.

Chuỗi phải sử dụng dấu ngoặc kép

Chuỗi phải sử dụng dấu ngoặc kép — JSON xác định chuỗi là các ký tự được bao quanh bởi `"`, có dấu gạch chéo ngược thoát nếu cần. Một trích dẫn không có vai trò là dấu phân cách chuỗi. Khi trình xác thực đáp ứng `'Ada'`, nó không bắt đầu một chuỗi rồi phản đối nội dung của chuỗi đó; nó từ chối chính dấu nháy đơn mở đầu. Điều này áp dụng như nhau cho tên thuộc tính và giá trị chuỗi, mặc dù JavaScript cho phép kiểu trích dẫn cho các chữ riêng của nó.

Việc chuyển đổi dấu ngoặc kép đòi hỏi sự cẩn thận hơn là thay thế mọi dấu nháy đơn trên toàn cầu. Dấu nháy đơn bên trong văn bản, chẳng hạn như `Ada's profile` là nội dung thông thường khi giá trị được trích dẫn kép, trong khi dấu ngoặc kép hiện có bên trong nội dung đó phải được thoát. Biểu mẫu JSON hợp lệ là `"Ada's "profile""`.

Khóa phải được trích dẫn chuỗi

Khóa phải là chuỗi trích dẫn — JavaScript đối tượng bằng chữ cho phép tên kiểu định danh chẳng hạn như `{name: 1}` và tên được tính toán chẳng hạn như `{[expression]: 1}`. JSON không cho phép viết tắt. Sau dấu ngoặc nhọn hoặc dấu phẩy mở, thành viên tiếp theo phải bắt đầu bằng chuỗi trích dẫn kép, theo sau là dấu hai chấm. Biểu diễn hợp lệ là `{"name": 1}`. Trình xác thực trỏ đến `n` đang xác định chính xác vị trí cần báo giá.

Trích dẫn mọi khóa cũng loại bỏ sự mơ hồ xung quanh dấu cách, dấu gạch nối và các từ dành riêng. JavaScript có thể yêu cầu cú pháp nguồn khác cho những trường hợp đó, nhưng JSON sử dụng một quy tắc nhất quán: `"display-name"`, `"first name"` và `"default"` đều là tên thành viên thông thường. Các phím trông như số cũng là các chuỗi.

Giá trị JSON đơn giản là không có

Các giá trị JSON đơn giản là không có — từ vựng giá trị của nó là đối tượng, mảng, chuỗi, số, `true`, `false` và `null`. Không có `undefined`, `NaN`, `Infinity`, hàm, biểu thức chính quy, chữ BigInt hoặc Date. Ngữ pháp không có nhận xét và số không thể sử dụng dấu thập lục phân, nhị phân, dấu cộng ở đầu hoặc dấu phân cách số JavaScript. Mỗi cấu trúc được mượn cuối cùng sẽ đạt đến một ký tự không thể bắt đầu hoặc tiếp tục giá trị JSON hợp lệ.

Việc chuyển đổi yêu cầu quyết định về dữ liệu hơn là thủ thuật đánh vần. Chỉ thay thế `undefined` bằng `null` nếu giá trị trống rõ ràng khớp với hợp đồng ứng dụng; nếu không thì loại bỏ thành viên hoặc cung cấp một giá trị thực. Mã hóa ngày tháng dưới dạng chuỗi đã thỏa thuận, thường là ISO 8601. Biểu thị các số không hữu hạn theo việc nhận API thay vì phát minh ra mã thông báo JSON.

Ví dụ đã hoạt động: chuyển đổi kết xuất bảng điều khiển thành JSON hợp lệ

Ví dụ đã hoạt động: chuyển đổi kết xuất bảng điều khiển thành JSON hợp lệ — bắt đầu bằng `{name: 'Ada', active: true, score: NaN, updated: new Date()}`. Trích dẫn `name`, `active`, `score` và `updated` bằng dấu ngoặc kép. Thay đổi giá trị tên thành chuỗi trích dẫn kép. Quyết định rằng điểm không có sẵn phải là `null` và thay thế biểu thức hàm tạo bằng chuỗi dấu thời gian thực tế mà nó dự định tạo ra. Tài liệu hiện chỉ chứa JSON thành viên và giá trị.

Hình dạng hoàn thiện có thể là `{"name":"Ada","active":true,"score":null,"updated":"2026-03-21T10:00:00Z"}`. Xác thực sau mỗi danh mục sửa chữa vì lỗi đầu tiên có thể ẩn cú pháp chỉ JavaScript sau này. Định dạng kết quả được chấp nhận sau đó sẽ hiển thị cấu trúc của nó mà không thực hiện bất kỳ chuyển đổi nào nữa.

Bẫy ngược — JSON hợp lệ mà JavaScript sẽ đọc khác, chẳng hạn như số nguyên rất lớn và khóa __proto__

Bẫy ngược — JSON hợp lệ vẫn có thể thu được hành vi hoặc giới hạn cụ thể của JavaScript sau khi phân tích cú pháp. Các số JSON không có giới hạn độ chính xác tích hợp trong ngữ pháp nhưng JSON.parse tạo ra các giá trị số JavaScript. Do đó, một số nguyên nằm ngoài phạm vi an toàn có thể được làm tròn một cách im lặng. Nếu mọi chữ số đều quan trọng, hãy mã hóa mã định danh dưới dạng chuỗi hoặc sử dụng trình phân tích cú pháp và kiểu dữ liệu được thiết kế để bảo toàn các số có độ chính xác tùy ý thay vì tin tưởng vào việc kiểm tra cú pháp thành công.

Tên thành viên `"__proto__"` cũng hợp lệ JSON và JSON.parse tạo tên thành viên đó làm thuộc tính dữ liệu riêng. Rắc rối có thể bắt đầu sau này nếu mã ứng dụng sao chép các thuộc tính được phân tích cú pháp vào một đối tượng khác có hành vi gán hoặc hợp nhất không an toàn. Việc xác thực chứng minh rằng văn bản tuân theo ngữ pháp JSON; nó không chứng minh được rằng mọi chìa khóa đều an toàn cho mọi người tiêu dùng.

Điều này không bao gồm những gì

Điều này không bao gồm những gì — JSON5, JSONC và các ngôn ngữ cấu hình cố tình chấp nhận nhận xét, dấu phẩy ở cuối, tên không có dấu ngoặc kép hoặc chuỗi có dấu ngoặc đơn. Các định dạng đó giải quyết các vấn đề soạn thảo khác nhau và cần các trình phân tích cú pháp triển khai ngữ pháp của riêng chúng. Trình xác thực JSON nghiêm ngặt không nên âm thầm diễn giải lại chúng vì việc chấp nhận cú pháp bổ sung sẽ khiến kết quả của nó gây hiểu lầm đối với các API, siêu dữ liệu gói và các đích đến khác thực sự yêu cầu tiêu chuẩn JSON.

Sự khác biệt này cũng loại trừ đánh giá JavaScript tùy ý. Việc chạy văn bản đã dán thông qua `eval` hoặc hàm tạo Hàm chỉ để biến một nghĩa đen của đối tượng thành dữ liệu có thể thực thi các getters, lệnh gọi hoặc các biểu thức thù địch khác. Nếu nguồn đáng tin cậy JavaScript dưới sự kiểm soát của bạn, hãy tuần tự hóa giá trị thực bằng JSON.stringify. Nếu nguồn là văn bản không đáng tin cậy thì không thực thi nó.

Bài học rút ra: chữ là mã, JSON là dữ liệu

Bài học rút ra: nghĩa đen là mã, JSON là dữ liệu — sự giống nhau về hình ảnh không làm cho ngữ pháp của chúng có thể hoán đổi cho nhau. JSON yêu cầu các chuỗi và tên thành viên được trích dẫn kép, chỉ cho phép một tập hợp nhỏ các loại giá trị cố định và không chứa nhận xét hoặc biểu thức thực thi. Chẩn đoán dòng và cột đánh dấu vị trí đầu tiên mà nguồn được sao chép để lại ngữ pháp đó. Việc sửa điểm đó và xác thực lại sẽ đáng tin cậy hơn việc áp dụng tìm kiếm và thay thế rộng rãi cho kết xuất bảng điều khiển.

Khi bạn kiểm soát giá trị JavaScript, hãy tạo JSON bằng JSON.stringify thay vì sao chép biểu diễn bảng điều khiển của nó. Khi bạn nhận được văn bản, chỉ phân tích cú pháp văn bản đó bằng trình phân tích cú pháp cho định dạng được khai báo và không bao giờ thực thi văn bản đó dưới dạng lối tắt. Xác thực JSON thành công thiết lập cú pháp chứ không phải độ chính xác về số, sự phù hợp với lược đồ hoặc xử lý thuộc tính an toàn ở phía dưới.