डेवलपर टूल · URL एनकोडर और डिकोडर
एस्केप() बनाम एनकोडयूआरआईकंपोनेंट: JavaScript की URL एन्कोडिंग कैसे विकसित हुई
· पेजभूमि
जावास्क्रिप्ट URL एन्कोडिंग इतिहास
JavaScript में URL-एन्कोडिंग फ़ंक्शंस की तीन पीढ़ियाँ हैं, और सबसे पुराना अभी भी उत्पादन कोड में छिपा हुआ है। यह पोस्ट बताती है कि एस्केप() क्या गलत करता है, ES3 ने URI फ़ंक्शंस क्यों जोड़े और वे संरक्षित क्यों करते हैं! *' ( ).
लीगेसी लॉग में %u20AC - एस्केप() का अचूक फिंगरप्रिंट और इसके कारण होने वाली डिकोडिंग विफलता
एक विरासत JavaScript फ़ाइल में अप्रचलित एस्केप() फ़ंक्शन का उपयोग करके एक URL-एन्कोडिंग कॉल शामिल है। लॉग फ़ाइल या त्रुटि संदेश के आउटपुट में अनुक्रम %u20AC शामिल है - अप्रचलित एस्केप() फ़ंक्शन का एक अचूक फिंगरप्रिंट जिसका उपयोग कोई और नहीं करता है। यह क्रम किसी भी मानक URL एन्कोडिंग से मेल नहीं खाता है, और RFC 3986 या WHATWG नियमों पर निर्मित डिकोडर इसे नहीं पहचान पाएगा। आधुनिक टूलों के माध्यम से डेटा को राउंड-ट्रिप नहीं किया जा सकता है। यह कोड का एक सामान्य चिह्न है जो ES3 से पहले का है और 1990 के दशक से इसे अपडेट नहीं किया गया है।
एस्केप() फ़ंक्शन को नेटस्केप युग में डिज़ाइन किया गया था, इससे पहले JavaScript में मानक या औपचारिक URL एन्कोडिंग नियम थे। यह %uXXXX नोटेशन का उपयोग करके अधिकांश गैर-ASCII वर्णों को एन्कोड करता है, एक चार-अंकीय हेक्साडेसिमल कोड जिसे कोई और उपयोग नहीं करता है और कोई मानक कहीं भी परिभाषित नहीं करता है। यह ब्राउज़र के भीतर एकबारगी उपयोग के लिए समझ में आता है, लेकिन इसने URL मानकों के साथ संगतता को तोड़ दिया और डेटा को अन्यत्र डिकोड करना असंभव बना दिया।
एस्केप() और अनस्केप(): एक नेटस्केप-युग डिज़ाइन - लैटिन-1 धारणाएँ, %uXXXX आविष्कार और यह कभी भी किसी मानक से मेल क्यों नहीं खाता
escape() और unescape() इनपुट को Latin-1 (ISO 8859-1) मानते हैं—यह UTF-8 और Unicode से पुरानी कैरेक्टर एनकोडिंग है। वे हर कैरेक्टर को हेक्साडेसिमल कोड में बदलते हैं: हाई-बिट Latin-1 कैरेक्टर के लिए %XX और Latin-1 से बाहर के लिए %uXXXX। emoji जैसे गैर-Latin-1 कैरेक्टर को दिखाया ही नहीं जा सकता। फ़ंक्शन सरल और तेज़ हैं, लेकिन किसी भी आधुनिक इस्तेमाल के लिए पूरी तरह गलत हैं।
मानकों के अस्तित्व में आने से पहले दोनों फ़ंक्शन JavaScript में जोड़े गए थे। ES3 द्वारा 1999 में उचित URL एन्कोडिंग पेश करने के तुरंत बाद उन्हें हटा दिया गया। वे पिछड़ी अनुकूलता के लिए JavaScript में बने रहते हैं—उन्हें हटाने से प्राचीन कोड टूट जाएगा। लेकिन किसी भी नए कोड का उपयोग कभी नहीं करना चाहिए। वे एक विरासत अवशेष हैं.
ES3 (1999) encodeURI और encodeURIComponent जोड़ता है - UTF-8 प्रतिशत-एन्कोडिंग RFC 2396 के साथ संरेखित है
ES3 ने दो फ़ंक्शन पेश किए: encodeURI और encodeURIComponent। दोनों UTF-8 प्रतिशत-एन्कोडिंग करते हैं: गैर-ASCII वर्णों को UTF-8 बाइट्स में परिवर्तित करते हैं, फिर प्रत्येक बाइट को %HH के रूप में लिखते हैं। दोनों RFC 2396 के साथ संरेखित हैं, जो उस समय चालू था। RFC 3986 बाद में आया और एन्कोडिंग व्यवहार में कोई बदलाव नहीं आया। ये फ़ंक्शन आज भी मानक हैं और इनका उपयोग किया जाना चाहिए।
एनकोडयूआरआई संपूर्ण URI को एन्कोड करने के लिए है; encodeURIComponent एक क्वेरी मान या पथ खंड की तरह, URI के अंदर एक घटक को एन्कोड करने के लिए है। अंतर बिल्कुल गंभीर है और इसे गलत समझना आसान है। encodeURI संरचनात्मक वर्णों को संरक्षित करता है जैसे: / ? # @ = & और ;. encodeURIComponent उन सभी को एनकोड करता है, जिससे वे बड़े URI के अंदर एम्बेड करने के लिए सुरक्षित हो जाते हैं।
क्यों ! * ' ( ) अभी भी एन्कोडेड नहीं हैं - RFC 2396 'चिह्न' वर्ण RFC 3986 द्वारा स्थानांतरित किए जाने के बाद भाषा में जमे हुए हैं
दोनों फ़ंक्शन इन वर्णों को अनएन्कोडेड छोड़ देते हैं: अक्षर, अंक, हाइफ़न (-), अंडरस्कोर (_), अवधि (.), टिल्ड (~), और पांच विराम चिह्न! *' ( ). अंक RFC 2396 से आए, जिसने उन्हें अनारक्षित "चिह्न" वर्णों के रूप में सूचीबद्ध किया। RFC 3986 2005 में आया और उन पांचों को एक अलग कैटेगरी में ले गया, लेकिन JavaScript ने पहले से ही 1999 में encodeURI और encodeURIComponent को फ्रीज कर दिया था। वे जिन पात्रों को अकेला छोड़ देंगे उन्हें बदलने से मौजूदा कोड टूट जाएगा, इसलिए वे रुके रहे।
बैकवर्ड अनुकूलता के लिए उन पांच चिह्नों को अनएनकोडेड रखने के निर्णय का मतलब है कि JavaScript की एन्कोडिंग या तो RFC 3986 या WHATWG मानक से पूरी तरह मेल नहीं खाती है। यह व्यावहारिक उपयोग के लिए काफी करीब है, और अब इसे बदलना पूरी तरह से असंभव है। यह API स्थिरता का एक पाठ है: एक बार जब आप व्यवहार को स्थिर कर देते हैं, तो मानक विकसित होने पर भी आप इसे नहीं बदल सकते।
कार्यान्वित उदाहरण: एस्केप, एनकोडयूआरआई और एनकोडयूआरआईकंपोनेंट के माध्यम से एक ही स्ट्रिंग - तीन आउटपुट की तुलना
स्ट्रिंग "आर एंड डी (अनुसंधान) = कैफे" लें। इसे एस्केप(), एनकोडयूआरआई और एनकोडयूआरआईकंपोनेंट के माध्यम से चलाएं। एस्केप() "R%26D%20(research)%20%3D%20caf%E9's" उत्पन्न करता है, जो अनएन्कोडेड कोष्ठक और एपोस्ट्रोफ को प्रतिशत-एन्कोडेड एम्परसेंड और बराबर के साथ मिलाता है। एन्कोडयूआरआई "R&D%20(research)%20=%20caf%C3%A9's" उत्पन्न करता है, एम्परसेंड और बराबर चिह्नों को अकेला छोड़ देता है क्योंकि वे संरचनात्मक होते हैं। encodeURIComponent "R%26D%20%28research%29%20%3D%20caf%C3%A9%27s" उत्पन्न करता है, जो कोष्ठक और एपोस्ट्रोफ सहित सब कुछ एन्कोडिंग करता है।
उसी स्ट्रिंग को URL एनकोडर और डिकोडर में चिपकाएँ और अंतर देखने के लिए encodeURI और encodeURIComponent के बीच स्विच करें। फिर निरीक्षण करें कि एस्केप() क्या उत्पन्न करेगा (आप इसे ब्राउज़र कंसोल में कॉल कर सकते हैं, हालांकि यह आपको चेतावनी देगा)। आप तुरंत देखेंगे कि तीन फ़ंक्शन तीन पूरी तरह से अलग-अलग परिणाम उत्पन्न करते हैं।
एस्केप() से दूर माइग्रेट करना - पुरानी कॉल को सही आधुनिक फ़ंक्शन पर मैप करना और संग्रहीत %uXXXX डेटा को संभालना
एस्केप() का उपयोग करने वाले पुराने कोड को अद्यतन किया जाना चाहिए। यदि एस्केप() का उपयोग URI घटक को एन्कोड करने के लिए किया गया था, तो इसे encodeURIComponent से बदलें। यदि इसका उपयोग पूर्ण URI को एन्कोड करने के लिए किया गया था, तो एन्कोडयूआरआई का उपयोग करें। संग्रहीत डेटा के लिए जिसमें %uXXXX अनुक्रम शामिल हैं, आपको एक कस्टम डिकोडर की आवश्यकता है: प्रत्येक %uXXXX को यूनिकोड कोड बिंदु में कन्वर्ट करें, फिर कोड बिंदुओं को एक स्ट्रिंग में एकत्र करें। JavaScript का अंतर्निर्मित अनस्केप() %uXXXX को पढ़ेगा, लेकिन परिणाम सही नहीं हो सकता है UTF-8।
एस्केप() को बदलने के बाद, गैर-ASCII वर्ण, विराम चिह्न और विशेष वर्ण वाले स्ट्रिंग के साथ कोड का परीक्षण करें। आउटपुट को अब आधुनिक टूलों और मानकों से मेल खाना चाहिए। यदि आपका कोड ES3 से काफी पहले का है, तो यह अन्य पुराने पैटर्न का भी उपयोग कर सकता है; एक व्यापक ऑडिट प्रयास के लायक है।
इसमें क्या शामिल नहीं है - URL और URLSearchParams API, जो अलग से कवर किए गए हैं
URL और URLSearchParams API, बहुत बाद में जोड़े गए, URL निर्माण और घटक एन्कोडिंग के लिए उच्च-स्तरीय इंटरफ़ेस प्रदान करते हैं। वे सभी पलायन को स्वचालित रूप से संभालते हैं और WHATWG URL मानक से बिल्कुल मेल खाते हैं। वे आधुनिक JavaScript में प्रोग्रामेटिक रूप से URL बनाने का पसंदीदा तरीका हैं।
यह पोस्ट केवल एन्कोडिंग फ़ंक्शंस को कवर करती है, उन उच्च-स्तरीय APआई को नहीं। URL और URLSearchParams संरचना को पार्स करते हैं, घटक नियमों का चयन करते हैं और परिणाम को क्रमबद्ध करते हैं, जबकि encodeURIComponent एक आपूर्ति की गई स्ट्रिंग को यह जाने बिना बदल देता है कि इसे कहां रखा जाएगा। वह अंतर सीमा है: एक पुराने एस्केप() कॉल को इस आधार पर माइग्रेट करें कि क्या उसने किसी मान या पते को संभाला है, फिर एक अलग रिफैक्टर के रूप में संरचित APआई के साथ आसपास के मैन्युअल कॉन्सटेनेशन को बदलने पर विचार करें।
टेकअवे: तीन फ़ंक्शन, एक जीवित जोड़ी - कैसे URL एनकोडर और डिकोडर आधुनिक एनकोडयूआरआई और एनकोडयूआरआईकंपोनेंट व्यवहार को एक साथ दिखाते हैं
आधुनिक JavaScript विकास को एनकोडयूआरआई या एनकोडयूआरआईकंपोनेंट का उपयोग करना चाहिए, कभी भी एस्केप() नहीं करना चाहिए। फ़ंक्शंस को 1999 में मानकीकृत किया गया था और तब से उनमें कोई बदलाव नहीं हुआ है। वे गैर-ASCII वर्णों को UTF-8 बाइट्स के रूप में एन्कोड करते हैं और मानक आरक्षित वर्णों को सही ढंग से संभालते हैं। URL एनकोडर और डिकोडर टूल दोनों कार्यों को लागू करता है और आपको उनके व्यवहार को एक साथ देखने देता है, जिससे आपके घटक के लिए सही को चुनना आसान हो जाता है।
यदि आपको पुराने लॉग या संग्रहीत डेटा में %u अनुक्रम मिलते हैं, तो वे एस्केप() आउटपुट हैं और उन्हें माइग्रेट किया जाना चाहिए। एक बार जब आप पैटर्न की पहचान कर लेते हैं तो माइग्रेशन सीधा हो जाता है। आधुनिक कोड को कभी भी उनका उत्पादन नहीं करना चाहिए।