URL encode करें

कोई स्ट्रिंग चिपकाइए और उसे URL में इस्तेमाल के लिए percent-escaped रूप में पाइए। जो एक फ़ैसला सचमुच मायने रखता है वह अंदाज़े से तय होने के बजाय आपके सामने विकल्प के रूप में रखा जाता है: आप किसी पते के भीतर जाने वाला मान encode कर रहे हैं, या पूरा पता जिसकी तिरछी लकीरें और प्रश्नचिह्न ढाँचा हैं और जिन्हें बचना है। जो इन दोनों को गड्डमड्ड कर देता है उसे ऐसी URL मिलती है जो ठीक दिखती है और कहीं और ले जाती है।

मान ? & = / और # को escape करता है। पूरा पता उन्हें रहने देता है, क्योंकि वहाँ वे ढाँचा हैं।

नतीजा

आप लिखते जाइए, जवाब यहाँ आता जाएगा।

  • कहाँ चलता है

    कुछ भी अपलोड नहीं होता, क्योंकि कोई फ़ाइल है ही नहीं — गणना इसी पन्ने में होती है।

  • न कतार, न खाता

    यह उतनी ही तेज़ी से जवाब देता है जितनी आपकी मशीन देती है, और कभी नहीं पूछता कि आप कौन हैं।

  • जितनी बार चाहें

    न कुछ गिना जाता है, न कोई सीमा है — दोबारा जवाब देने में हमारा कुछ ख़र्च नहीं होता।

काम कैसे करता है

  1. टेक्स्ट खाने में चिपकाइए।
  2. बताइए यह क्या है: पते के भीतर का मान, या पूरा पता। इसी से तय होता है कि ? और & escape होंगे या नहीं।
  3. नतीजा कॉपी कर लीजिए। कुछ अपलोड नहीं हुआ।

यह औज़ार सिर्फ़ एक सवाल पूछता है

URL हिस्सों से बनी होती है, और जो अक्षर उन हिस्सों को अलग करते हैं — `/`, `?`, `&`, `=`, `#` — वे उस भूमिका में होने पर ढाँचा हैं और बाक़ी जगह डेटा। पूरे पते को encode करते समय उन्हें छोड़ना ही पड़ता है वरना वह पता रह ही नहीं जाता; किसी अलग मान को encode करते समय उन्हें escape करना ही पड़ता है वरना मान वहीं ख़त्म होकर कुछ और शुरू हो जाता है।

यही ठीक-ठीक `encodeURI` और `encodeURIComponent` का फ़र्क़ है, और वेब पर टूटे हुए redirect पैरामीटरों की अधिकांश संख्या यहीं से आती है: कोई `?wapas=https://udaharan.example/a?b=c`, जहाँ दूसरा प्रश्नचिह्न कभी escape नहीं हुआ, इसलिए उसके बाद का सब कुछ बाहरी URL का हिस्सा बन जाता है। लिंक जाँच में चलता है, जहाँ मंज़िल के पास query string नहीं होती, और उत्पादन में विफल होता है, जहाँ होती है।

Percent बाइट ले जाता है, अक्षर नहीं

Percent की शृंखला एक `%` और उसके बाद दो hexadecimal अंक होती है, और वह एक बाइट बताती है। ASCII से बाहर के अक्षरों को कई शृंखलाएँ चाहिए, और देवनागरी को हमेशा तीन, क्योंकि UTF-8 उसे तीन बाइट में लिखता है: «क» `%E0%A4%95` है।

गिनती चौंकाती है: «नमस्ते» छह code point हैं, इसलिए 18 percent शृंखलाएँ, यानी 54 अक्षर। जिन जगहों पर URL की लंबाई की कोई सीमा टकराती है — पुराने proxy, कुछ लॉग-तंत्र, कुछ ईमेल क्लाइंट — वहाँ हिंदी खोज-शब्द वाला पता उतने ही अंग्रेज़ी शब्दों वाले पते से कई गुना लंबा हो जाता है, और यह वह बात है जो अंग्रेज़ी में जाँची गई सीमा कभी नहीं दिखाती।

वे पाँच अक्षर जो हस्ताक्षर तोड़ते हैं

`encodeURIComponent` विस्मयादिबोधक चिह्न, उर्ध्वल्पविराम, दोनों कोष्ठक और तारांकन को escape किए बिना छोड़ देता है। RFC 3986 इन्हें आरक्षित मानता है, इसलिए सख़्ती से मानक का पालन करने वाला encoder इन्हें escape करता है — और दोनों की असहमति ठीक इन पाँच अक्षरों पर होती है, जो साधारण टेक्स्ट में लगातार आते हैं।

फ़र्क़ तभी दिखता है जब बीच में कोई हस्ताक्षर हो। OAuth 1.0 और AWS Signature version 4 encode की गई स्ट्रिंग पर hash निकालते हैं, इसलिए बिना escape हुआ एक अकेला उर्ध्वल्पविराम hash बदल देता है और रिक्वेस्ट मना कर दी जाती है — ऐसी त्रुटि के साथ जो credentials की बात करती है और आपको ग़लत जगह ढूँढ़ने भेज देती है। यहाँ का सख़्त विकल्प पाँचों को escape करता है।

स्पेस: %20 या plus का चिह्न

दोनों दिखते हैं और दोनों एक ही नियम से नहीं आते। `%20` percent encoding है और URL के किसी भी हिस्से में सही है। Plus का चिह्न `application/x-www-form-urlencoded` से आता है, यानी उस रूप से जिसमें HTML का फ़ॉर्म भेजता है, जहाँ स्पेस `+` लिखा जाता है — मौजूदा विनिर्देश से पुरानी परिपाटी, जो इसलिए बची हुई है कि फ़ॉर्म आज भी ऐसा ही करते हैं।

Path में `+` सचमुच plus होता है। Query string में लगभग हर सर्वर उसे स्पेस पढ़ता है, क्योंकि फ़ॉर्म वाली encoding ऐसा कहती है — इसलिए किसी query मान में असली plus को `%2B` लिखना पड़ता है, वरना वह ग़ायब हो जाता है। यह encoder `%20` बनाता है, जो दोनों जगहों में से किसी में भी दुविधा भरा नहीं है।

दो बार encode करना, और उसे पहचानना कैसे है

पहले से encode की गई स्ट्रिंग को दोबारा encode करने पर ख़ुद `%` escape हो जाता है, इसलिए `%20` `%2520` बन जाता है। इसमें शामिल किसी भी हिस्से के लिए यह त्रुटि नहीं है — यह «%20» टेक्स्ट का पूरी तरह वैध encoding है — और इसीलिए दोहरी encoding उस बिंदु तक बची रहती है जहाँ कोई उपयोक्ता किसी शीर्षक में `नमस्ते%20दुनिया` पढ़ता है।

संकेत यह है कि जहाँ `%` होना चाहिए वहाँ `%25` दिखे। ऐसा दिखे तो आपकी शृंखला में कहीं कोई चीज़ पहले से encode हुए मान को दोबारा encode कर रही है, आम तौर पर इसलिए कि कोई framework यह आपके लिए कर देता है और कोई template उसे दोहरा देता है। हल यह है कि दोनों में से एक जगह हटाई जाए, न कि आख़िर में दो बार decode कर दिया जाए।

जिन्हें कभी escape नहीं करना चाहिए

अक्षर, अंक और चार चिह्न `-`, `_`, `.` और `~` को RFC 3986 «unreserved» कहता है और इन्हें कभी escape नहीं किया जाना चाहिए। जो encoder बिंदु की जगह `%2E` बनाता है वह ज़्यादा सख़्त नहीं है: वह ग़लत है, क्योंकि कुछ तंत्र उसे वापस सामान्य कर देते हैं और कुछ नहीं, और इस तरह दो URL जिन्हें एक ही होना चाहिए था अलग हो जाती हैं।

व्यवहार में: जब टेक्स्ट ज़्यादातर अक्षरों का हो और encode की गई स्ट्रिंग में बेहिसाब percent शृंखलाएँ दिखें, तो वह आम तौर पर ज़रूरत से ज़्यादा encode करने वाले औज़ार से आई होती है। यह तब तक निरापद है जब तक कोई उस पर हस्ताक्षर या cache key न निकाले — और तब यही वजह होती है कि दो तंत्रों की बात नहीं बनती।

पुराना escape() और वह %u0915 वाला रूप

JavaScript का पुराना `escape()` फलन देवनागरी के लिए percent शृंखलाएँ बनाता ही नहीं। वह `%u0915` जैसा कुछ बनाता है, यानी अक्षर का code point सीधे लिख देता है। यह रूप किसी भी URL मानक में नहीं है; इसे कोई सर्वर decode नहीं करता, और यह किसी लॉग में साबुत पड़ा रह जाता है।

यह अब भी दिखता है क्योंकि पुराने पन्नों का JavaScript बदला नहीं गया। अगर आपके किसी पैरामीटर में `%u` दिखे तो निदान पूरा हो चुका: वह मान `escape()` से निकला है और उसे `encodeURIComponent` से निकलना चाहिए। यह पन्ना हमेशा UTF-8 वाली percent शृंखलाएँ बनाता है, यानी हिंदी अक्षर के लिए तीन।

Fragment कभी भेजा नहीं जाता

`#` के बाद की हर चीज़ ब्राउज़र में ही रह जाती है। वह किसी रिक्वेस्ट में नहीं दिखती, किसी सर्वर तक नहीं पहुँचती और किसी access log में दर्ज नहीं होती। यह HTTP का गुण है, कोई निजता-सुविधा नहीं, और यह दोनों तरफ़ काटता है।

यह काम का है क्योंकि fragment में रखा मान सर्वर तक नहीं जाता — ऐतिहासिक रूप से यही वजह थी कि OAuth के token वहीं सफ़र करते थे। यह असुविधाजनक है क्योंकि वह फिर भी ब्राउज़र के इतिहास में, कुछ स्क्रिप्टों की referrer-शृंखला में और साझा किए गए हर लिंक में रह जाता है। «सर्वर तक नहीं पहुँचता» का मतलब «निजी है» नहीं होता।

Host percent-encode नहीं होता, Punycode में बदलता है

देवनागरी वाला डोमेन escape नहीं होता: वह Punycode में बदलता है। `भारत.example` `xn--h2brj9c.example` बन जाता है, और यही वह रूप है जो DNS में सचमुच मौजूद है, क्योंकि नाम-तंत्र सिर्फ़ ASCII जानता है।

जो encoder host को किसी मान की तरह बरतता है वह ऐसा पता बनाता है जिसे कोई DNS हल नहीं करता। इसीलिए यहाँ पूरे पते वाला तरीक़ा host को हाथ नहीं लगाता — और इसीलिए, अगर आप देवनागरी डोमेन वाली URL जोड़ रहे हैं, तो host का रूपांतरण अलग क़दम है, इस क्रिया का हिस्सा नहीं। भारत में `.भारत`, `.भारतम्` और दूसरी लिपियों वाले IDN चलन में हैं, इसलिए यह यहाँ अपवाद जितना दुर्लभ नहीं है।

DPDP Act के लिहाज़ से इसका क्या मतलब है

जो encode होता है वह आम तौर पर किसी URL में जाकर बैठता है, और URL सर्वर के लॉग में, ब्राउज़र के इतिहास में और अगले क्लिक के referrer हेडर में रह जाती हैं। अगर मान में कोई ईमेल, कोई पहचान-संख्या या कोई निजी खोज-शब्द है, तो इस्तेमाल होते ही वह कई जगह पहुँच चुका होता है।

यह पन्ना जो हिस्सा हल करता है वह यह है कि encoding आपके डिवाइस पर होती है: वह मान हम तक नहीं पहुँचता। जो हिस्सा यह हल नहीं कर सकता वह कहने लायक़ है — निजी डेटा के अनजाने में दर्ज हो जाने की सबसे आम जगह URL का कोई पैरामीटर ही है।

URL encode करें: आम सवाल

मुझे तीनों में से कौन-सा तरीक़ा चाहिए?

अगर टेक्स्ट किसी पते के भीतर जाने वाला मान है तो पहला: वह ? & = / और # को escape करता है। अगर वह पूरा पता है तो दूसरा, जो उन्हें रहने देता है क्योंकि वहाँ वे ढाँचा हैं। तीसरा तभी चाहिए जब बीच में कोई हस्ताक्षर हो।

मेरा एक हिंदी अक्षर तीन शृंखलाओं में क्यों बदलता है?

क्योंकि percent encoding बाइट ले जाती है और UTF-8 देवनागरी को तीन बाइट में लिखता है: «क» %E0%A4%95 है। इसीलिए हिंदी खोज-शब्द वाली URL अंग्रेज़ी वाली से कई गुना लंबी हो जाती है।

मुझे अपनी URL में %2520 दिख रहा है, इसका क्या मतलब है?

कि वह दो बार encode हो चुकी है: %20 दोबारा किसी encoder से गुज़रा और उसका % escape हो गया। हल यह है कि दो चरणों में से एक हटाया जाए, न कि आख़िर में दो बार decode किया जाए।

स्पेस %20 के रूप में या plus के रूप में?

%20 URL के हर हिस्से में सही है। + का मतलब स्पेस सिर्फ़ query string में होता है, फ़ॉर्म वाली encoding की विरासत से; path में plus सचमुच plus है। यहाँ %20 बनता है, जो दुविधा भरा नहीं है।

क्या टेक्स्ट मेरे डिवाइस से बाहर जाता है?

नहीं। Encoding इसी पन्ने पर होती है। पर यह ध्यान रखिए कि URL इस्तेमाल हो जाने के बाद वह मान सर्वर के लॉग में, इतिहास में और referrer हेडर में रह जाता है।

और टूल्स