ค้นหาเว็บไซต์

javascript - JSON ที่ถูกต้องน้อยที่สุดคืออะไร?


ฉันได้อ่านคำอธิบาย JSON อย่างรอบคอบที่ http://json.org/ แต่ฉันก็ไม่แน่ใจว่ารู้คำตอบของคำถามง่ายๆ นั้นหรือไม่ สตริงใดเป็น JSON ที่ถูกต้องที่มีค่าต่ำสุดได้

  • "string" เป็น JSON ที่ถูกต้องหรือไม่?
  • 42 เป็นตัวเลขง่าย ๆ ที่เป็น JSON ที่ถูกต้องหรือไม่?
  • true เป็นค่าบูลีน ใช้ได้กับ JSON หรือไม่?
  • {} คือวัตถุว่าง เป็น JSON ที่ถูกต้องหรือไม่?
  • [] คืออาร์เรย์ว่าง ใช่ JSON ที่ถูกต้องหรือไม่?

คำตอบ #1

ในเวลาที่เขียน JSON ถูกอธิบายเพียงอย่างเดียวใน RFC4627 มันอธิบาย (ที่เริ่มต้นของ "2") ข้อความ JSON ว่าเป็นวัตถุหรืออาร์เรย์ที่ถูกจัดเรียงเป็นลำดับ

ซึ่งหมายความว่า เพียง {} และ [] เท่านั้นที่เป็นสตริง JSON ที่ถูกต้องและสมบูรณ์ในตัวแยกวิเคราะห์และตัวแปลงสตริงซึ่งปฏิบัติตามมาตรฐานนั้น

อย่างไรก็ตาม การแนะนำ ECMA-404 ทำให้สิ่งนั้นเปลี่ยนไป และคำแนะนำที่อัปเดตสามารถอ่านได้ที่นี่ ฉันยังได้เขียนบล็อกโพสต์เกี่ยวกับประเด็นนี้ด้วย


เพื่อทำให้เรื่องสับสนมากขึ้น อย่างไรก็ตาม วัตถุ JSON (เช่น JSON.parse() และ JSON.stringify()) ที่มีอยู่ในเว็บเบราว์เซอร์ถูกมาตรฐานใน ES5 และนิยามอย่างชัดเจนถึงข้อความ JSON ที่ยอมรับได้ดังนี้:

รูปแบบแลกเปลี่ยน JSON ที่ใช้ในข้อกำหนดนี้เป็นไปตามที่ระบุโดย RFC 4627 ทุกประการ โดยมีข้อยกเว้นสองประการ:

  • การสร้าง JSONText ระดับบนสุดของไวยากรณ์ JSON ของ ECMAScript อาจประกอบด้วย JSONValue ใด ๆ แทนที่จะจำกัดอยู่เพียง JSONObject หรือ JSONArray ตามที่กำหนดโดย RFC 4627

  • snipped

นี่จะหมายความว่า ค่าทุกค่า ของ JSON (รวมทั้งสตริง null และตัวเลข) ถูกยอมรับโดยวัตถุ JSON แม้ว่าวัตถุ JSON จะปฏิบัติตาม RFC 4627 โดยทางเทคนิคก็ตาม

โปรดทราบว่าดังนั้นคุณสามารถแปลงตัวเลขเป็นสตริงในเบราว์เซอร์ที่ตรงตามมาตรฐานได้ผ่าน JSON.stringify(5) ซึ่งอาจถูกปฏิเสธโดยตัวแยกวิเคราะห์อื่นที่ปฏิบัติตาม RFC4627 แต่ไม่ได้มีข้อยกเว้นเฉพาะดังที่กล่าวข้างต้น Ruby ตัวอย่างเช่น ดูเหมือนจะเป็นตัวอย่างหนึ่งที่ รับเฉพาะ อ็อบเจกต์และอาเรย์เป็น root ในทางกลับกัน PHP จะเพิ่มข้อยกเว้นเฉพาะว่า "มันยังสามารถเข้ารหัสและถอดรหัสประเภทสคาร์ลาร์และ NULL"

คำตอบ #2

มีเอกสารอย่างน้อยสี่ฉบับที่สามารถถือว่าเป็นมาตรฐาน JSON บนอินเทอร์เน็ต RFCs ที่อ้างถึงทั้งหมดอธิบายประเภท MIME application/json นี่คือสิ่งที่แต่ละฉบับกล่าวเกี่ยวกับค่าระดับบนสุด และว่ามีสิ่งอื่นใดนอกเหนือจากวัตถุหรืออาร์เรย์ที่อนุญาตให้ใช้ในระดับบนสุดหรือไม่:

RFC-4627: ไม่ใช่.

ข้อความ JSON คือ ลำดับของโทเค็น ชุดของโทเค็นประกอบด้วยอักขระเชิงโครงสร้างหกตัว สตริง ตัวเลข และชื่อตัวอักษรสามชื่อ

ข้อความ JSON เป็นวัตถุหรือตารางที่ถูกจัดเรียงเป็นลำดับ

JSON-text=วัตถุ/อาเรย์

โปรดทราบว่า RFC-4627 ถูกระบุว่าเป็น "ข้อมูลเชิงให้ความรู้" แทนที่จะเป็น "มาตรฐานที่เสนอ" และมันถูกเลิกใช้โดย RFC-7159 ซึ่งต่อมาถูกเลิกใช้โดย RFC-8259

RFC-8259: ใช่.

ข้อความ JSON คือ ลำดับของโทเค็น ชุดของโทเค็นประกอบด้วยอักขระเชิงโครงสร้างหกตัว สตริง ตัวเลข และชื่อจริงสามชื่อ

ข้อความ JSON คือค่าที่ถูกทำให้เป็นลำดับข้อความ โปรดทราบว่าข้อกำหนด JSON บางฉบับก่อนหน้านี้จำกัดให้ข้อความ JSON ต้องเป็นวัตถุหรืออาเรย์ การใช้งานที่สร้างเฉพาะวัตถุหรืออาเรย์เมื่อมีการเรียกข้อความ JSON จะสามารถทำงานร่วมกันได้ในแง่ที่ว่าการใช้งานทั้งหมดจะยอมรับสิ่งเหล่านี้ว่าเป็นข้อความ JSON ที่ถูกต้อง

JSON-text=ws ค่า ws

RFC-8259 มีวันที่ ธันวาคม 2017 และถูกทำเครื่องหมายว่า "มาตรฐานอินเทอร์เน็ต".

ECMA-262: ใช่.

ไวยากรณ์ทางวากยสัมพันธ์ของ JSON กำหนดข้อความ JSON ที่ถูกต้องโดยอ้างอิงจากโทเค็นที่กำหนดโดยไวยากรณ์ทางเล็กซิคัลของ JSON สัญลักษณ์เป้าหมายของไวยากรณ์คือ JSONText

ไวยากรณ์ JSONText :

ค่า JSON

ค่า JSON :

ค่า null ของ JSON

ค่าลิตเทอรัลบูลีน JSON

วัตถุ JSON

อาเรย์ของ JSON

JSONString

จำนวน JSON

ECMA-404: ใช่.

ข้อความ JSON คือ ลำดับของโทเค็นที่สร้างจากจุดรหัสยูนิโค้ดซึ่งสอดคล้องกับไวยากรณ์ค่าของ JSON ชุดของโทเค็นประกอบด้วยโทเค็นโครงสร้างหกประเภท สตริง ตัวเลข และโทเค็นชื่อสามประเภท

คำตอบ #3

ตามคำนิยามเก่าใน RFC 4627 (ซึ่งถูกยกเลิกในเดือนมีนาคม 2014 โดย RFC 7159) สิ่งเหล่านั้นทั้งหมดถือเป็น "ค่า JSON" ที่ถูกต้อง แต่มีเพียงสองค่าล่าสุดเท่านั้นที่จะประกอบเป็น "ข้อความ JSON" ที่สมบูรณ์:

ข้อความ JSON เป็นวัตถุหรือตารางที่ถูกจัดเรียงเป็นลำดับ

ขึ้นอยู่กับตัวแยกวิเคราะห์ที่ใช้ ค่าของ "JSON" เพียงค่าเดียวอาจถูกยอมรับก็ได้ ตัวอย่างเช่น (ยึดตามคำศัพท์ "ค่า JSON" กับ "ข้อความ JSON"):

  • ฟังก์ชัน JSON.parse() ที่ได้มาตรฐานในเบราว์เซอร์สมัยใหม่ในตอนนี้ ยอมรับค่า "JSON" ใด ๆ
  • ฟังก์ชัน PHP json_decode ถูกแนะนำในเวอร์ชัน 5.2.0 ซึ่งรับเฉพาะ "ข้อความ JSON" ทั้งหมดเท่านั้น แต่ถูกแก้ไขให้รับค่า "JSON" ใดๆ ก็ได้ในเวอร์ชัน 5.2.1
  • ฟังก์ชัน json.loads ของ Python ยอมรับค่า "JSON ทุกชนิด" ตามตัวอย่างในหน้าคู่มือหน้านี้
  • ตัวตรวจสอบที่ http://jsonlint.com คาดหวัง 'ข้อความ JSON' อย่างสมบูรณ์
  • โมดูล Ruby JSON จะยอมรับเฉพาะ "ข้อความ JSON" เต็มรูปแบบเท่านั้น (อย่างน้อยก็จากความคิดเห็นในหน้าคู่มือนี้)

ความแตกต่างนั้นก็คล้ายกับความแตกต่างระหว่าง “เอกสาร XML” และ “เศษ XML” แม้ว่าในเชิงเทคนิค <foo /> จะเป็นเอกสาร XML ที่มีรูปแบบถูกต้อง (จะเขียนให้ดีกว่านี้เป็น <?xml version="1.0" ?><foo /> แต่ตามที่กล่าวในความคิดเห็น การประกาศ <?xml ในเชิงเทคนิคเป็นทางเลือกได้)

บทความที่เกี่ยวข้อง