JSON ขั้นต่ำที่ถูกต้องคืออะไร?


174

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

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

12
การทดสอบที่jsonlint.comการทดสอบสองครั้งสุดท้ายนั้นถูกต้อง
ironcito

1
ตัวแยกวิเคราะห์ JSON บางตัวต้องการอาร์เรย์หรือวัตถุ พวกเขาบ่นเพียงแค่ตัวเลขหรือสตริง
akonsu

3
ณ ตอนนี้สิ่งเหล่านั้นใช้ได้
Brian Colavito


คำตอบสั้น ๆ - {}
Tukaram Bhosale

คำตอบ:


156

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

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

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


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

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

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

  • snipped

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

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


@amdorra: คุณจะเฉพาะเจาะจงมากขึ้นที่คุณเห็นว่า?
Matt

5
JSON ไม่ใช่คำนามดังนั้น "JSON" จึงไม่มีความหมาย "ค่า JSON" ใด ๆ คือ "ค่า JSON" แต่ตัวแยกวิเคราะห์มักจะคาดหวัง "ข้อความ JSON" ตามที่กำหนดไว้ใน RFC นั้น
IMSoP

2
ไม่ดีของฉันฉันจะลบคำตอบของฉันแล้ว
amdorra

1
@jmoreno คุณช่วยอธิบายความคิดเห็นของคุณได้ไหม? ที่คุณพูดtrue, falseหรือnullอยู่คนเดียวเป็นข้อความ JSON ถูกต้อง? คุณช่วยอ้างอิงแหล่งที่มาได้เพราะนี่ขัดแย้งกับคำตอบ / ความคิดเห็นอื่น ๆ ที่นี่หรือไม่?
Lawrence Johnston

2
@jmoreno: แน่นอนข้อความจากส่วนที่ 2 "ข้อความ JSON เป็นวัตถุหรืออาร์เรย์ต่อเนื่อง" ตรงข้ามกับสิ่งนั้น? JSON Lint ไม่คิดว่าไม่ใช่อาเรย์หรือวัตถุที่ถูกต้อง ไม่มีข้อโต้แย้งว่าสตริงนั้นเป็นตัวอักษร JSON ที่ถูกต้องหรือไม่ สิ่งนี้จบลงแล้วว่าสตริงนั้นถูกต้องหรือไม่
แมตต์

42

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

RFC-4627 :ไม่

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

ข้อความ JSON เป็นวัตถุหรืออาร์เรย์ที่ทำให้เป็นอนุกรม

JSON-text = object / array

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

RFC-8259 :ใช่

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

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

JSON-text = ws ค่า ws

RFC-8259 ลงวันที่ธันวาคม 2560 และทำเครื่องหมายว่า "INTERNET STANDARD"

ECMA-262 :ใช่

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

ไวยากรณ์ JSONText:

JSONValue

JSONValue:

JSONNullLiteral

JSONBooleanLiteral

JSONObject

JSONArray

JSONString

JSONNumber

ECMA-404 :ใช่

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


10

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

ข้อความ JSON เป็นวัตถุหรืออาร์เรย์ที่ทำให้เป็นอนุกรม

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

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

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


การเปรียบเทียบ XML อาจไม่เหมาะสมเนื่องจากเอกสาร XML นั้นถูกต้องทั้งหมดโดยไม่ต้องมีการประกาศ XML เพิ่มเติม ดูคำแนะนำ XML ได้ที่w3.org/TR/xml/#sec-well-formed
Gunther

@Gunther อ่าใช่ฉันลืมไปแล้วว่ามันเป็นตัวเลือกทางเทคนิคแม้ว่าจะได้รับการสนับสนุนอย่างสูงก็ตาม
IMSoP

@Gunther: การ nitpick: <foo />เป็นรูปแบบที่ดีเอกสาร XML แต่ไม่ถูกต้องอย่างใดอย่างหนึ่ง (แต่เป็นเรื่องจริงเหมือนกัน<?xml version="1.0" ?><foo />)
ruakh

@ruakh สิ่งที่น่าสนใจคำจำกัดความที่นี่หมายถึง XML สามารถ "ถูกต้อง" กับ DTD เท่านั้นซึ่งหมายความว่าเอกสาร XML มีน้อยมากเนื่องจาก DTD นั้นเขียนและประกาศในทางปฏิบัติน้อยมาก (เมื่อเทียบกับรูปแบบคำจำกัดความของสคีมาเช่น XSD หรือ RelaxNG) . ฉันถูกตรวจสอบเพราะถ้าคุณจะสามารถใช้งานได้กับสคีภายนอกโดยไม่ต้องอ้างอิงถึงมันแล้ว<foo /> อาจจะหรืออาจจะไม่ถูกต้องกับคีมาโดยเฉพาะอย่างยิ่งแต่นั่นไม่ใช่สิ่งที่รัฐมาตรฐาน
IMSoP

4

ข้อมูลจำเพาะ ecma อาจมีประโยชน์สำหรับการอ้างอิง:

http://www.ecma-international.org/ecma-262/5.1/

ฟังก์ชันวิเคราะห์คำแยกวิเคราะห์ข้อความ JSON (สตริงที่จัดรูปแบบ JSON) และสร้างค่า ECMAScript รูปแบบ JSON เป็นรูปแบบที่ จำกัด ของตัวอักษร ECMAScript วัตถุ JSON รับรู้เป็นวัตถุ ECMAScript อาร์เรย์ JSON ถูกรับรู้เป็น ECMAScript arrays สตริง JSON, ตัวเลข, บูลีนและ null ถูกรับรู้เป็น ECMAScript Strings, ตัวเลข, บูลีนและ null JSON ใช้ชุดอักขระสีขาวที่ จำกัด มากขึ้นกว่า WhiteSpace และอนุญาตให้โค้ด Unicode จุด U + 2028 และ U + 2029 ปรากฏโดยตรงในตัวอักษร JSONString โดยไม่ต้องใช้ลำดับการยกเว้น กระบวนการแยกวิเคราะห์คล้ายกับ 11.1.4 และ 11.1.5 ตามข้อ จำกัด ของไวยากรณ์ JSON

JSON.parse("string"); // SyntaxError: Unexpected token s
JSON.parse(43); // 43
JSON.parse("43"); // 43
JSON.parse(true); // true
JSON.parse("true"); // true
JSON.parse(false);
JSON.parse("false");
JSON.parse("trueee"); // SyntaxError: Unexpected token e
JSON.parse("{}"); // {}
JSON.parse("[]"); // []

4
ในขณะที่การอ้างอิงที่มีประโยชน์นั่นคือข้อมูลจำเพาะของตัวแยกวิเคราะห์ JSON เฉพาะ (หนึ่งที่กำหนดไว้ในมาตรฐาน ECMAScript) ไม่ได้สำหรับรูปแบบตัวเอง json.orgระบุไว้อย่างชัดเจนว่า JSON เป็น "อิสระทางภาษาอย่างสมบูรณ์" ดังนั้นจึงไม่มีตัวแยกวิเคราะห์ที่ถูกต้อง
IMSoP

1
JavaScript / ECMAScipt เป็นแรงบันดาลใจให้กับ JSON และเป็นผู้ใช้ แต่ไม่ใช่ "บ้าน" ของมัน JSON ได้มาจากสัญกรณ์ตามตัวอักษรใน (รุ่นก่อนหน้าทั้งหมด) ECMAScript แต่ไม่เหมือนกัน JSON.parseฟังก์ชั่นถูกเพิ่มเข้ามาแล้วรุ่นที่ใหม่กว่ามาตรฐาน ECMAScript อยู่บนพื้นฐานของหลักไวยากรณ์ Crockford และอา
IMSoP

4
คุณควรทำJSON.parse("\"string\"");
ericbn

4

JSON ย่อมาจาก JavaScript Object Notation เฉพาะ{}และ[]กำหนดวัตถุ Javascript ตัวอย่างอื่น ๆ คือตัวอักษรตามตัวอักษร มีประเภทของวัตถุใน Javascript สำหรับทำงานกับค่าเหล่านั้น แต่นิพจน์เป็นการแสดง"string"ซอร์สโค้ดของค่าตัวอักษรไม่ใช่วัตถุ

โปรดทราบว่า JSON ไม่ใช่ Javascript มันเป็นสัญลักษณ์ที่แสดงถึงข้อมูล มันมีโครงสร้างที่ง่ายและ จำกัด ข้อมูล JSON มีโครงสร้างโดยใช้{},:[]อักขระ คุณสามารถใช้ค่าตัวอักษรในโครงสร้างนั้นเท่านั้น

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


1
ฉันคิดว่าการหาคำตอบจากทิศทางนี้จะทำให้ชัดเจนมากกว่า: ต้นกำเนิดของชื่อไม่มีรายละเอียดเกี่ยวกับมาตรฐานและประเภทที่มีใน JavaScript อาจเป็นแรงบันดาลใจให้กับประเภทใน JSON แต่ไม่มีข้อกำหนด ตรงกับที่พวกเขา คำแนะนำเกี่ยวกับjson.orgทำให้สิ่งนี้ชัดเจน: "JSON เป็นรูปแบบข้อความที่เป็นภาษาที่สมบูรณ์"
IMSoP

@IMSoP ฉันเห็นด้วยทั้งหมด ฉันผสมประเภท Javascript กับ JSON และไม่ถูกต้อง ฉันจะอัปเดตคำตอบของฉัน
ปฏิกิริยา

2

ใช่ใช่ใช่ใช่และใช่ ทั้งหมดเป็นตัวอักษรค่า JSON ที่ถูกต้อง

อย่างไรก็ตามทางการRFC 4627ระบุว่า:

ข้อความ JSON เป็นวัตถุหรืออาร์เรย์ที่ทำให้เป็นอนุกรม

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



-2

เพียงทำตามแผนผังทางรถไฟที่ให้ไว้ในหน้าjson.org [] และ {} เป็นวัตถุ JSON ที่ถูกต้องที่เป็นไปได้ขั้นต่ำ ดังนั้นคำตอบคือ [] และ {}


3
มันไม่ใช่ FSM มันเป็นไวยากรณ์ และดูเหมือนจะไม่ได้ระบุว่าการผลิตใดเป็นกฎเริ่มต้น หากกฎเริ่มต้นarrayและobjectคุณจะถูกต้อง แต่ก็สมเหตุสมผลที่จะคาดหวังว่าvalueจะเป็นจุดเริ่มต้น

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

2
ไม่ใช่การตีความของคุณเกี่ยวกับกฎไวยากรณ์ใด ๆ ที่ฉันคัดค้านนั่นคือคุณเลือกสองกฎและถือว่าหนึ่งสามารถเริ่มจากกฎเหล่านั้นไม่ใช่จากกฎอื่น ๆ หากคุณดูvaluesกฎแทน (หรือเพิ่มเติมจาก) arrayและobjectกฎแล้วตัวเลขและสตริงแบบสแตนด์อโลนเป็นเอกสาร JSON ที่ถูกต้อง

-1 ประการแรกในขณะที่ @delnan ชี้ให้เห็นไม่มีอะไรในแผนภาพที่ json.org แสดงให้เห็นว่าข้อความ JSON แบบเต็มต้องเป็นวัตถุหรืออาร์เรย์ คุณเลือกทั้งสองอย่างโดยพลการไม่ได้ยึดถืออะไรบน json.org ประการที่สองการ nitpicking เหนือคำศัพท์: []ในขณะที่ข้อความ JSON ที่ถูกต้องภายใต้สเป็คทุกอย่างที่เคยมีความเห็นเกี่ยวกับเรื่องนี้ไม่ใช่ "วัตถุ JSON ที่ถูกต้อง" เนื่องจากไม่ใช่วัตถุ JSON "Object" ใน JSON หมายถึง{}เครื่องหมายโดยเฉพาะ; อาร์เรย์ JSON ไม่ใช่วัตถุ JSON
Mark Amery
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.