JSON Toolkit

RFC 8259 से JSON व्याकरण की सीमाएँ पढ़ना

मुख्य बात: RFC 8259 के व्याकरण उत्पादनों को सरल भाषा में बदलना: कौन से अक्षर सीधे आ सकते हैं, किन्हें escape करना होगा, और विनिर्देश जानबूझकर कहाँ जगह छोड़ता है।

शुरुआती~11 मिनट पढ़ें2026-10-30 को प्रकाशित2026-10-30 को अपडेट किया गया
RFC 8259 से JSON व्याकरण की सीमाएँ पढ़ने का कवर

सार: JSON सिंटैक्स त्रुटि आने पर पहला अवैध अक्षर खोजें और उसे single quote, trailing comma, टिप्पणी या नियंत्रण अक्षर में वर्गीकृत करें, पूरा दस्तावेज़ दोबारा न पढ़ें; एन्कोडिंग की ओर, BOM रहित UTF-8 की पुष्टि करें और 2^53 - 1 से बड़े पूर्णांक स्ट्रिंग के रूप में ले जाएँ।

विनिर्देश का मुख्य भाग केवल एक दर्जन पृष्ठों का है, फिर भी हर "MUST", "SHOULD" और "MAY" के पीछे वह घटना छिपी है जिसने कभी किसी टीम को पूरी रात जगाए रखा।

1. तीनों पाठ आपस में कैसे जुड़े हैं

JSON सीखते समय तीन संख्याएँ अक्सर उलझा देती हैं: RFC 4627, RFC 7159, RFC 8259, और ऊपर से ECMA-404। रिश्ता वास्तव में काफ़ी स्पष्ट है:

पाठ तारीख स्थिति मुख्य अंतर
RFC 4627 2006 अधिक्रमित शीर्ष स्तर object या array ही होना चाहिए
RFC 7159 2014 अधिक्रमित शीर्ष स्तर को किसी भी JSON मान तक ढीला किया
RFC 8259 2017.12 वर्तमान मानक स्पष्ट UTF-8, interoperability मार्गदर्शन जोड़ा
ECMA-404 2013, दूसरा संस्करण 2017.12 व्याकरण विनिर्देश केवल व्याकरण परिभाषित करता है, एन्कोडिंग या परिवहन नहीं

कौन सा पढ़ें? अकेले RFC 8259 काफ़ी है। ECMA-404 अपने व्याकरण भाग में समतुल्य है; अंतर यह है कि RFC 8259 "UTF-8 में परिवहन" और "implementation को किन interoperability मुद्दों पर ध्यान देना चाहिए" भी तय करता है।

2. छह मान प्रकार

विनिर्देश के व्याकरण उत्पादनों को एक ही आरेख में समेटा जा सकता है:

JSON-text  = ws value ws
value      = object / array / number / string / "true" / "false" / "null"
object     = "{" [ member *( "," member ) ] "}"
member     = string ws ":" ws value
array      = "[" [ value *( "," value ) ] "]"

केवल छह मुख्य बिंदु हैं:

  1. Object कुरघनी कोष्ठक (curly braces) इस्तेमाल करते हैं, सदस्य comma से अलग होते हैं, और अंतिम सदस्य के बाद comma अनुमत नहीं;
  2. Array वर्ग कोष्ठक इस्तेमाल करते हैं, तत्व comma से अलग होते हैं, और trailing comma उसी तरह अनुमत नहीं;
  3. संख्या में अग्रणी + नहीं, अग्रणी शून्य नहीं (01 अवैध है), अकेला दशमलव बिंदु नहीं (1. अवैध है), और NaN या Infinity नहीं;
  4. स्ट्रिंग दोहरे उद्धरण इस्तेमाल करनी चाहिए; single quote अवैध है;
  5. Boolean और null लोअरकेस शाब्दिक रूप हैं; True और NULL दोनों अवैध हैं;
  6. केवल खाली जगह अक्षर 0x20 (space), 0x09 (tab), 0x0A (line feed) और 0x0D (carriage return) संरचनात्मक तत्वों के बीच आ सकते हैं।

नीचे दिया टुकड़ा वैध JSON है, हालाँकि बहुत लोग पहली बार देखकर मान लेते हैं कि यह गलत है — क्योंकि यह शीर्ष स्तर पर अकेली स्ट्रिंग है:

"just a string"

RFC 7159 से शीर्ष स्तर वाकई कोई भी मान हो सकता है। फिर भी API में केवल object या array इस्तेमाल करने की सिफ़ारिश रहती है; कारण धारा 6 में है।

3. स्ट्रिंग के भीतर सीधे क्या आ सकता है

यही वह भाग है जहाँ "मेरी मशीन पर तो चलता है" सबसे आसानी से धोखा देता है। स्ट्रिंग के लिए विनिर्देश के नियम हैं:

  • सीधे आने योग्य अक्षर: %x20-21, %x23-5B, %x5D-10FFFF;
  • दूसरे शब्दों में, दोहरा उद्धरण " (0x22) और backslash \ (0x5C) escape होने चाहिए;
  • 0x20 से नीचे के सभी नियंत्रण अक्षर escape होने चाहिए, जिनमें line feed, tab और carriage return शामिल हैं;
  • उपलब्ध escape क्रम केवल \", \\, \/, \b, \f, \n, \r, \t और \uXXXX हैं।
{
  "ok": "Chinese text, emoji 🎉 and full-width symbols can be written directly",
  "escaped": "A line break goes here\nand a tab\tfinishes it",
  "control": "\u0007 is the bell character and must be escaped",
  "quote": "He said: \"don't use single quotes\""
}

\/ एक पुराना escape है (यह </script> को जल्दी बंद होने से रोकता है)। आधुनिक परिदृश्यों में इसकी ज़रूरत कम पड़ती है, पर parser को इसे समर्थन देना ही है।

4. एन्कोडिंग: UTF-8, BOM नहीं

RFC 8259 की धारा 8.1 तीन बातें कहती है:

  1. interoperability के लिए इस्तेमाल किया जाने वाला JSON पाठ UTF-8 में एन्कोडेड होना चाहिए;
  2. Implementation पाठ की शुरुआत में BOM (EF BB BF) नहीं जोड़ सकते;
  3. Parser अधिक मज़बूती के लिए BOM को अनदेखा कर सकते हैं।

वास्तविक दुनिया में दो विशिष्ट विफलताएँ:

  • Windows Notepad "UTF-8 with BOM" के रूप में सहेजता है, फ़ाइल JSON.parse द्वारा Unexpected token के साथ अस्वीकार हो जाती है;
  • GBK में सहेजी गई चीनी JSON फ़ाइल केवल UTF-8 में डिकोड करने वाली पाइपलाइन पर गड़बड़ पाठ बन जाती है, फिर भी व्याकरण संयोग से पार हो जाता है, इसलिए त्रुटि व्यवसाय परत तक टल जाती है।

समाधान सीधा है: फ़ाइल पढ़ते समय BOM हटाएँ, फिर स्पष्ट रूप से UTF-8 में डिकोड करें; लिखते समय सुनिश्चित करें कि BOM न जुड़े।

/**
 * Removes the UTF-8 BOM at the start of a string.
 * @param text The original text
 * @returns The text without a BOM
 */
function stripBom(text: string): string {
  return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
}

यहाँ मीडिया प्रकार पर एक टिप्पणी: application/json अब charset पैरामीटर स्वीकार नहीं करता; लिखने से त्रुटि नहीं आती, पर यह पुरानी आदत है।

5. तीन जगहें जहाँ विनिर्देश जानबूझकर जगह छोड़ता है

विनिर्देश जहाँ चीज़ें तय करने से इनकार करता है, वहीं से implementation के अंतर पैदा होते हैं।

1. संख्याओं की परास और परिशुद्धता

RFC 8259 केवल यह कहता है "यह विनिर्देश संख्याओं की परास या परिशुद्धता सीमित नहीं करता", और साथ में बताता है कि अधिकांश implementation IEEE 754 double precision इस्तेमाल करते हैं। इसका अर्थ है कि वही 9223372036854775807 JavaScript में 9223372036854776000 बन जाता है, फिर भी Java के long में सटीक रहता है।

निष्कर्ष: 2^53 - 1 से बड़े पूर्णांक और कई दशमलव अंकों की परिशुद्धता चाहने वाली धनराशि हमेशा स्ट्रिंग के रूप में ले जाएँ, और schema में pattern स्पष्ट लिखें।

2. दोहराई गई key

विनिर्देश का शब्दांकन है "object के भीतर नाम अद्वितीय होने चाहिए (SHOULD)"; जब वे न हों तो क्या करें, यह नहीं कहता।

  • JSON.parse अंतिम को रखता है;
  • कुछ parser पहली को रखते हैं;
  • कुछ लाइब्रेरी सीधे त्रुटि देती हैं।

निष्कर्ष: दोहराई गई key न लिखें, और अपने validator में किसी विशेष व्यवहार पर निर्भर न रहें। Build समय पर "दोहरी key पहचान" का चरण जोड़ना बाद में जाँच करने से कहीं सस्ता है।

3. गहराई और लंबाई की सीमाएँ

विनिर्देश nesting की गहराई पर कोई सीमा नहीं लगाता, पर हर implementation की अपनी है। V8 दसियों हज़ार स्तर के nesting पर RangeError: Maximum call stack size exceeded फेंकता है। सर्वर को अपनी सीमाएँ लगानी होंगी; यह सुरक्षा आवश्यकता है, विनिर्देश आवश्यकता नहीं।

6. प्रति-उदाहरणों से अपनी समझ जाँचें

नीचे की हर पंक्ति अवैध JSON है। उन्हें parser को दें और देखें कि त्रुटि संदेश मदद करते हैं या नहीं:

{ 'name': 'json' }        // single quotes
{ name: "json" }          // key name not quoted
{"a": 1,}                 // trailing comma
[1, 2, 3,]                // trailing comma in an array
{"a": 01}                 // leading zero
{"a": +1}                 // leading plus sign
{"a": .5}                 // missing integer part
{"a": NaN}                // non-standard literal
{"a": undefined}          // not a JSON value
{"a": 1} // comment       // comment

एक रोचक सीमा मामला: {"a": 1} के बाद टिप्पणी JSON5 में वैध, JSONC में वैध, और मानक JSON में अवैध है। इसलिए "कॉन्फ़िगरेशन फ़ाइल चलती है पर API अस्वीकार कर देता है" लगभग हमेशा बोली (dialect) की समस्या है।

7. उत्पादन चेकलिस्ट

  • [ ] बाहर भेजा जाने वाला सारा JSON application/json इस्तेमाल करता है, charset के बिना;
  • [ ] फ़ाइल पढ़ने/लिखने की पाइपलाइन BOM हटाती है और स्पष्ट UTF-8 इस्तेमाल करती है;
  • [ ] 2^53 से बड़े पूर्णांक स्ट्रिंग के रूप में ले जाए जाते हैं और schema में अंकित हैं;
  • [ ] दोहराई गई key build समय पर पकड़ी जाती हैं;
  • [ ] सर्वर request body का आकार और nesting की गहराई सीमित करता है;
  • [ ] सार्वजनिक API के शीर्ष-स्तरीय मान object या array हैं, कभी अकेले scalar नहीं।

अक्सर पूछे जाने वाले प्रश्न

कोई पाठ वैध JSON है या नहीं, जल्दी कैसे पता करूँ?

पाठ को parser या ऑनलाइन पार्सिंग टूल को दें, पहले अवैध अक्षर का स्थान पढ़ें, फिर उसे RFC 8259 के छह मान प्रकारों और खाली जगह के नियमों से मिलाएँ। शीर्ष स्तर कोई भी JSON मान हो सकता है, पर संरचनात्मक तत्वों के बीच केवल space, tab, line feed और carriage return अनुमत हैं। एक single quote, बिना उद्धरण key, trailing comma या टिप्पणी का अर्थ है कि यह मानक JSON नहीं है।

JSON को UTF-8 होना और BOM न लाना क्यों ज़रूरी है?

RFC 8259 की धारा 8.1 interoperability के लिए इस्तेमाल होने वाले JSON पाठ को UTF-8 में एन्कोडेड होने की शर्त लगाती है, कहती है कि implementation शुरुआत में BOM नहीं जोड़ सकते, और मज़बूती के लिए parser को BOM अनदेखा करने देती है। BOM वाली फ़ाइल JSON.parse द्वारा Unexpected token के साथ अस्वीकार हो जाती है, भले आँख को कुछ गलत न लगे। इसलिए पढ़ते समय BOM हटाएँ और स्पष्ट रूप से UTF-8 में डिकोड करें।

इन व्याकरण सीमाओं से बचने के लिए JSON5 या JSONC इस्तेमाल करूँ?

हाँ, पर केवल कॉन्फ़िगरेशन फ़ाइलों जैसे स्थानीय पढ़ने के लिए; सिस्टमों के बीच अदला-बदली होने वाला डेटा अब भी मानक JSON होना चाहिए। प्रति-उदाहरण दिखाते हैं कि {"a": 1} के बाद टिप्पणी JSON5 और JSONC में वैध है पर मानक JSON में अवैध, इसीलिए "कॉन्फ़िग फ़ाइल चलती है पर API अस्वीकार कर देता है" लगभग हमेशा बोली की समस्या है। रूपांतरित करते समय पहले टिप्पणियाँ, single quote और trailing comma हटाएँ और परिणाम मानक parser को दें।