आँकड़ों और विज्ञापन के लिए कुकीज़
हम आँकड़ों और विज्ञापन के लिए कुकीज़ इस्तेमाल करते हैं, दोनों Google को जाती हैं। मना करने से आपको दिखने वाली किसी चीज़ में कोई फ़र्क़ नहीं पड़ता।निजता पेज पढ़ें
अक्षर-संदर्भों वाला टेक्स्ट चिपकाइए और पढ़िए कि उसमें क्या लिखा है। नाम वाले, दशमलव और hexadecimal — तीनों पहचाने जाते हैं। इससे ज़्यादा मायने यह रखता है कि यह कैसे होता है: एक तालिका से, न कि आपके टेक्स्ट को किसी तत्व में डालकर ब्राउज़र से पूछकर — और यही फ़र्क़ तय करता है कि decode करते समय किसी और का markup कुछ कर सकता है या नहीं।
कहाँ चलता है
कुछ भी अपलोड नहीं होता, क्योंकि कोई फ़ाइल है ही नहीं — गणना इसी पन्ने में होती है।
न कतार, न खाता
यह उतनी ही तेज़ी से जवाब देता है जितनी आपकी मशीन देती है, और कभी नहीं पूछता कि आप कौन हैं।
जितनी बार चाहें
न कुछ गिना जाता है, न कोई सीमा है — दोबारा जवाब देने में हमारा कुछ ख़र्च नहीं होता।
Entity हल करने का ज़ाहिर तरीक़ा यह है कि टेक्स्ट को किसी तत्व में लिखकर उसका `textContent` पढ़ लिया जाए। यही वह तरीक़ा भी है जिससे इस क़िस्म के आधे औज़ार अपने लिए छेद बना लेते हैं: टेक्स्ट के भीतर पड़ा `<img src=x onerror=...>` सचमुच का तत्व बन जाता है, और तरीक़े के हिसाब से इससे या तो नेटवर्क रिक्वेस्ट चलती है या कोड चल जाता है।
यहाँ ऐसा नहीं होता, क्योंकि किसी भी क्षण HTML बनाया ही नहीं जाता। संदर्भ एक तालिका के सामने हल होते हैं और अंकों वाले गणना से निकाले जाते हैं: कोई बिंदु ऐसा नहीं है जहाँ आपका टेक्स्ट markup की तरह पढ़ा जाए। इसी कारण यह पन्ना कोई झलक भी नहीं दे सकता — वह ठीक उसी चीज़ पर लौटना होता जिससे बचा जा रहा है।
कोई संदर्भ `&` से शुरू होकर `;` पर ख़त्म होता है। बीच में `amp` या `nbsp` जैसा नाम होता है, या `#2325` जैसे दशमलव अंकों के साथ हैश, या `#x915` जैसे hexadecimal के साथ हैश और `x`। आख़िरी दो एक ही code point को दो आधारों में लिखते हैं।
व्यवहार में तीनों एक ही फ़ाइल में मिलते हैं, क्योंकि उन्हें अलग-अलग हिस्सों ने बनाया है: सामग्री-प्रबंधन तंत्र नाम वालों की ओर झुकते हैं, निर्यात दशमलव की ओर, XML के औज़ार hexadecimal की ओर। यहाँ तीनों एक जैसे बरते जाते हैं, इसलिए आपको यह जानने की ज़रूरत नहीं कि आपकी शृंखला के किस हिस्से की क्या पसंद थी।
ब्राउज़र उदार हैं: बिना अर्धविराम वाला `&` भी वे कई संदर्भों में हल कर देते हैं, क्योंकि पुराने पन्ने ऐसे ही लिखते थे और अनुकूलता जीत गई। यह उदारता HTML के मानक में दर्ज भी है, पर सिर्फ़ नामों की एक सीमित सूची के लिए और attribute के मानों के भीतर नहीं।
आपके लिए इसका मतलब यह है कि आपके डेटा में बिना अर्धविराम वाला `&` एक टिक-टिक करता बम है, क्योंकि अलग-अलग प्रोसेसर उसे अलग तरह बरतते हैं। यह औज़ार अर्धविराम की माँग करता है और अधूरे संदर्भों को जहाँ के तहाँ छोड़ देता है: जो दिखता रह जाता है वह ठीक वही जगह है जहाँ कोई चीज़ ग़लत बनी थी।
अगर नतीजे में अब भी `<` बचा है, तो इनपुट दोहरे encoding वाला था: उसमें `&lt;` था, और एक चक्र सही-सही `<` बनाता है। यह अधूरा नतीजा नहीं, सही नतीजा है — जो decoder तब तक चलता रहे जब तक कुछ entity जैसा न बचे, वह उस टेक्स्ट को भी नष्ट कर देता जहाँ `<` जान-बूझकर लिखा गया था।
साफ़ रास्ता यह है कि टेक्स्ट को यह जानते हुए दोबारा चलाया जाए कि आप ऐसा कर रहे हैं। अगर आपको आदतन दो चक्र चाहिए होते हैं, तो असली काम उस शृंखला में दोहरी encoding ढूँढ़ना है जो इसे बनाती है, न कि यहाँ दो बार बटन दबाना।
लगभग हमेशा किसी ऐसे मान से जो escape होकर सहेजा गया और जिसे template इंजन ने दिखाते समय दोबारा escape कर दिया। दोनों चरण अलग-अलग सही हैं; ग़लत यह है कि वे दो हैं। यह सिर्फ़ अंतिम पन्ने पर दिखता है, जहाँ उपयोक्ता ` ` को टेक्स्ट की तरह पढ़ते हैं।
दूसरा स्रोत आयात और स्थानांतरण हैं: किसी पुराने तंत्र का डेटा पहले से escape होकर आता है और नई रूटीन उसे कच्चा मानकर बरतती है। इसे भी दूसरे entity-नामों के आगे लगे `&` से पहचाना जाता है — यह दो परतों के एक पर एक चढ़ जाने का निशान है।
HTML5 में 2,200 से ज़्यादा नाम वाले संदर्भ परिभाषित हैं, `&` और `©` से लेकर उन गणितीय चिह्नों तक जिन्हें लगभग कोई नहीं लिखता। यह सूची जान-बूझकर जमा दी गई है: नए नाम नहीं जोड़े जाते, क्योंकि हर जुड़ाव पहले से मौजूद दस्तावेज़ों का अर्थ बदल देता।
व्यवहार में: अगर कोई नाम यहाँ हल नहीं होता तो या तो वह ग़लत लिखा है या वह कभी था ही नहीं। नए अक्षरों को अब नाम मिलते ही नहीं; 2014 के बाद Unicode ने जो कुछ जोड़ा है उसके लिए सिर्फ़ अंकों वाला रूप मौजूद है। देवनागरी के अक्षरों का भी कोई नाम वाला संदर्भ कभी नहीं रहा — वे हमेशा `क` जैसे अंकों में ही आते हैं।
`FFFF` से ऊपर के code point — emoji, कम चलने वाली लिपियाँ, कुछ गणितीय चिह्न — JavaScript में भीतर से दो इकाइयाँ लेते हैं, एक surrogate जोड़ा। जो decoder इसका हिसाब नहीं रखता वह एक पूरे अक्षर के बजाय दो टूटे आधे अक्षर बनाता है।
कभी-कभी ऐसे संदर्भ भी मिलते हैं जो जोड़े का हर आधा हिस्सा अलग-अलग लिखते हैं, क्योंकि किसी पुराने औज़ार ने ऐसे ही encode किया। सख़्त अर्थ में वे मान अवैध Unicode हैं; यहाँ उन्हें चुपचाप किसी प्रतिस्थापन-अक्षर में नहीं बदला जाता, ताकि दिखे कि समस्या स्रोत में है, दिखावे में नहीं।
` ` ऐसे अक्षर में बदलता है जो स्पेस जैसा दिखता है और है नहीं: उसका code point `A0` है, `20` नहीं। इसीलिए बाद में कोई तुलना, कोई ढूँढ़ो-और-बदलो या कोई `trim()` विफल होता है, बिना स्क्रीन पर किसी संदिग्ध चीज़ के।
इस परिवार की यह सबसे भारी ग़लती ठीक इसलिए है कि वह अदृश्य है। जो किसी सामग्री-प्रबंधन तंत्र या किसी वर्ड प्रोसेसर से कॉपी किया टेक्स्ट प्रोसेस करता है उसे इसका हिसाब रखना चाहिए: Word और अधिकतर दृश्य एडिटर कड़े स्पेस उदारता से लगाते हैं। अगर दो «साफ़ तौर पर एक जैसे» मान बराबर नहीं निकलते, तो सबसे पहले यहीं देखिए।
हिंदी सामग्री में `‌` और `‍` असामान्य नहीं हैं — ये zero-width non-joiner और zero-width joiner हैं। वे कुछ दिखाते नहीं और यह तय करते हैं कि संयुक्ताक्षर जुड़कर बनेगा या हलंत के साथ अलग दिखेगा, जैसे «क्ष» और «क्ष» के बीच का फ़र्क़।
Decode होने पर वे उन्हीं अदृश्य अक्षरों में बदल जाते हैं, और उसके बाद वही होता है जो कड़े स्पेस के साथ होता है: दो स्ट्रिंग जो पढ़ने में एक जैसी हैं तुलना में बराबर नहीं निकलतीं, और URL में जाने पर तीन-तीन percent शृंखलाओं में बदल जाती हैं। अगर हिंदी नामों की तुलना बिना किसी वजह के विफल हो रही है, तो इन दोनों को hex वाले पन्ने पर देख लेना सबसे तेज़ जाँच है।
इस खाने में अक्सर तीसरों का टेक्स्ट आता है: डेटाबेस का कोई अंश, कोई सपोर्ट टिकट, किसी feed की कोई प्रविष्टि जिसमें नाम और पते हों। चूँकि हल पन्ने पर ही होता है, उसमें से कुछ भी हम तक नहीं पहुँचता और न उस पर कोई प्रोसेसिंग की भूमिका बनती है।
साथ ही यह याद रखने लायक़ है कि decode किया हुआ टेक्स्ट परिभाषा से escape किए हुए टेक्स्ट से कम निरापद है — escape ही तो बचाव था। जो उसे किसी पन्ने पर वापस भेजने वाला है उसे उस मंज़िल के लिए दोबारा escape करना होगा; यह पढ़ने का औज़ार है, HTML परोसने वाली किसी शृंखला का आख़िरी क़दम नहीं।
क्योंकि इनपुट दोहरे encoding वाला था: उसमें `<` था और एक चक्र सही-सही `<` बनाता है। अगर यही चाहिए तो दोबारा चला लीजिए, और फिर उस शृंखला में वह चरण ढूँढ़िए जो दो बार escape करता है।
क्योंकि अर्धविराम के बिना संदर्भ अनिश्चित रहता है। ब्राउज़र अनुकूलता के लिए उदार हैं, पर एक जैसे नहीं; यहाँ उसे जस का तस छोड़ा जाता है ताकि दिखे कि कोई चीज़ कहाँ ग़लत बनी थी।
नहीं। संदर्भ एक तालिका के सामने हल होते हैं और अंकों वाले गणना से निकाले जाते हैं; किसी भी क्षण HTML बनाया नहीं जाता। इसी कारण यहाँ रेंडर की हुई झलक भी नहीं है।
A0 code point वाला कड़ा स्पेस। वह सामान्य स्पेस जैसा दिखता है पर दूसरा अक्षर है, इसलिए तुलनाएँ, ढूँढ़ो-और-बदलो और छाँटने वाले फलन उसे ख़ाली जगह की तरह नहीं बरतते।
नहीं। सब कुछ इसी पन्ने पर होता है; decode करने वाला कोई सर्वर है ही नहीं। लिखते हुए नेटवर्क पैनल इसकी पुष्टि कर देता है।