URL पार्सर
किसी भी URL को उसके घटकों में विश्लेषण करें · प्रोटोकॉल, होस्ट, पोर्ट, पथ, क्वेरी पैरामीटर और फ़्रैगमेंट।
URL की संरचना: छह घटक, एक लंबा इतिहास
एक URL को छह वैचारिक भागों में parse किया जाता है: scheme://userinfo@host:port/path?query#fragment। scheme client को बताता है कि कौन सा protocol उपयोग करना है (https, http, ftp, mailto, file, data) और यह एकमात्र भाग है जो हमेशा मौजूद होता है। userinfo घटक (username:password@) आधुनिक उपयोग में दुर्लभ है; browsers आमतौर पर इसे प्रदर्शित URLs से हटा देते हैं क्योंकि यह 1990 के दशक से phishing वेक्टर रहा है। host network स्थान है, एक पंजीकृत domain नाम, एक IP पता (IPv4 dotted-quad या वर्ग कोष्ठक में IPv6) या localhost जैसा एक विशेष नाम। port TCP/UDP port है (HTTP के लिए default 80, HTTPS के लिए 443, इत्यादि); जब छोड़ दिया जाता है, scheme का default लागू होता है। path slash-separated पदानुक्रम है जो host के भीतर संसाधन की पहचान करता है। query string (? के बाद सब कुछ) & से अलग किए गए key-value जोड़े ले जाती है, जो filtering, pagination, tracking, form submission के लिए उपयोग किए जाते हैं। fragment (# के बाद सब कुछ) URL का एकमात्र भाग है जो कभी server को नहीं भेजा जाता, इसे browser द्वारा पूरी तरह से client-side पर एक विशिष्ट section तक scroll करने के लिए या, single-page apps में, route अवस्था इंगित करने के लिए संसाधित किया जाता है।
Query string format में स्वयं एक विभाजन है: पारंपरिक ?key=value&key2=value2 RFC 3986 के अनुसार percent-encoded values के साथ, बनाम पुरानी form-encoded application/x-www-form-urlencoded परंपरा जहाँ + का अर्थ space होता है (मूल रूप से HTML form submissions के लिए)। अधिकांश parsers दोनों को संभालते हैं, लेकिन conversion असममित है: %20 हमेशा space में decode होता है; + केवल query string के अंदर space में decode होता है, path के अंदर कभी नहीं। यह जंगली में सबसे आम URL-parsing bugs में से एक है।
URL का संक्षिप्त इतिहास
URL (मूल रूप से «Universal Document Identifier», फिर «Universal Resource Locator») का आविष्कार Tim Berners-Lee ने मार्च 1989 में CERN में अपने «Information Management: A Proposal» memo (वह जिस पर उनके बॉस Mike Sendall ने «Vague but exciting» लिखा) और अगस्त 1991 के पहले सार्वजनिक रूप से browse करने योग्य web pages के बीच किया था। canonical पहली URL थी http://info.cern.ch/hypertext/WWW/TheProject.html, जो 6 अगस्त 1991 को पोस्ट की गई। 1992 की IETF चर्चाओं ने शब्दावली विवाद से बचने के लिए UDIs का नाम बदलकर URLs कर दिया। RFC 1738 («Uniform Resource Locators»), Berners-Lee, Masinter और McCahill द्वारा लिखा गया, दिसंबर 1994 में पहले औपचारिक URL syntax के रूप में प्रकाशित हुआ। RFC 2396 अगस्त 1998 में आया, URLs को व्यापक URI अवधारणा में सामान्यीकृत करते हुए। वर्तमान canonical spec है RFC 3986 («URI Generic Syntax»), जनवरी 2005 में प्रकाशित, Berners-Lee, Roy Fielding और Larry Masinter द्वारा संपादित, एक STD 66 Internet Standard, IETF का सर्वोच्च परिपक्वता स्तर। RFC 3986 वह है जिसे हर URL parser नाममात्र रूप से लक्षित करता है। व्यवहार में modern browsers कई edge cases में RFC 3986 से विचलित होते हैं, यही कारण है कि WHATWG url.spec.whatwg.org पर एक अलग URL Living Standard बनाए रखता है; WHATWG spec स्पष्ट रूप से समय के साथ RFC 3986 और RFC 3987 को obsolete करने का लक्ष्य रखती है, और दोनों अभी भी trailing whitespace handling, percent-encoding sets और Unicode normalisation जैसी चीज़ों पर भिन्न हैं।
अनारक्षित, आरक्षित और percent-encoded वर्ण
RFC 3986 §2.3 अनारक्षित वर्णों को परिभाषित करता है, किसी भी URI घटक में बिना percent-encoding के सुरक्षित गारंटी वाले एकमात्र वर्ण: A-Z, a-z, 0-9, हाइफन (-), अवधि (.), underscore (_), और tilde (~)। कुल 66 वर्ण। बाकी सब कुछ या तो किसी घटक में संरचनात्मक अर्थ वाला आरक्षित वर्ण है (gen-delims (:/?#[]@) और sub-delims (!$&'()*+,;=)) या «अन्य» है और यदि यह URI में दिखाई देता है तो percent-encoded होना चाहिए। Percent-encoding (RFC 3986 §2.1) किसी वर्ण के byte अनुक्रम (UTF-8 में जब तक scheme कुछ और न कहे) को लेता है और प्रत्येक byte को %HH से बदल देता है जहाँ HH byte का दो-अंकीय hex मान होता है। तो UTF-8 में encoded é (bytes 0xC3 0xA9) %C3%A9 बन जाता है; रूसी शब्द привет %D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82 बन जाता है, प्रति वर्ण दो bytes, छह %XX त्रिक और छह सिरिलिक अक्षरों के लिए 36 percent-encoded URL वर्ण।
Browsers percent-encoded paths को दो तरीकों से प्रदर्शित करते हैं: अधिकांश modern browsers (Chrome, Firefox, Safari) जब encoding वैध UTF-8 है तो address bar में मूल Unicode glyphs को decode और render करते हैं, लेकिन जब उपयोगकर्ता URL की प्रतिलिपि बनाता है तो literal percent-encoded रूप की प्रतिलिपि बनाते हैं। पुराने browsers और कई web logs केवल percent-encoded रूप दिखाते हैं, यही कारण है कि «सुंदर Unicode URLs» भ्रामक हो सकती हैं: वे address bar में सुंदर दिखती हैं और जिस भी text में साझा की जाती हैं वहाँ बदसूरत। RFC 3987 («Internationalized Resource Identifiers», IRIs), जनवरी 2005 में प्रकाशित, ने Unicode URLs को उनके non-encoded रूप में औपचारिक रूप दिया; Punycode (RFC 3492, मार्च 2003) परिभाषित करता है कि internationalised domain नाम DNS के लिए ASCII में label-by-label कैसे encoded होते हैं, चीनी top-level label 中国 xn--fiqs8s बन जाता है, इसलिए example.中国 DNS स्तर पर example.xn--fiqs8s के रूप में resolve होता है। canonical प्रदर्शन Wikipedia की IRI URLs है: https://ja.wikipedia.org/wiki/東京 किसी भी modern browser में काम करती है भले ही अंतर्निहित अनुरोध path को /wiki/%E6%9D%B1%E4%BA%AC के रूप में encode करता है।
WHATWG URL Standard, browsers वास्तव में क्या करते हैं
IETF का RFC 3986 एक बात कहता है; browsers कुछ थोड़ा अलग करते हैं। WHATWG (browser विक्रेताओं की मानक संस्था) URL Living Standard url.spec.whatwg.org पर अलग से बनाए रखती है जो algorithmic state machine का वर्णन करती है जिसे browsers वास्तव में चलाते हैं, जिसमें leading whitespace का संचालन, control वर्ण, घटक के अनुसार बदलने वाले percent-encoding sets, और Unicode normalization शामिल हैं। WHATWG spec वह है जिसे browser URL constructor (new URL(input)) implement करता है, और जिस पर Node.js, Deno और Bun सभी अपने built-in URL parsing के लिए converge हुए। Ada URL parser: Yagiz Nizipli, Daniel Lemire और अन्य लोगों द्वारा C++ में लिखा गया, WHATWG-conformant parser बन गया जो Node.js 18.16.0 (अप्रैल 2023) से Node.js URL parsing को संचालित करता है, पुराने url.parse() पथ को बदलते हुए; यह हर पिछले implementation से मापने योग्य रूप से तेज़ है और 2026 में उच्च-performance URL parsing के लिए de facto मानक है। RFC 3986 और WHATWG spec अभी भी पूरी तरह से reconciled नहीं हैं, और ऐतिहासिक विचलन अभी भी legacy code paths और पुराने runtime संस्करणों में दिखाई देता है।
Query string, और URLSearchParams API
Query string तकनीकी रूप से केवल «? के बाद और # से पहले सब कुछ» है, spec वास्तव में परिभाषित नहीं करती कि इसकी व्याख्या कैसे करनी है। & separators के साथ ?key=value&key=value परंपरा convention है, आवश्यकता नहीं। व्यवहार में, दो query string formats प्रबल हैं: application/x-www-form-urlencoded (default HTML form submission format, जहाँ + का अर्थ space है) और standard URI query convention (जहाँ space हमेशा %20 होता है)। Browser का URLSearchParams API (WHATWG URL Living Standard का हिस्सा, लगभग 2017 से सभी modern browsers में baseline) parsing के लिए दोनों formats को पारदर्शी रूप से संभालता है और stringifying करते समय form-encoded variant उत्सर्जित करता है। दोहराई गई keys कानूनी हैं: ?tag=red&tag=blue&tag=green मान्य है, और URLSearchParams.getAll('tag') ['red', 'blue', 'green'] लौटाता है। अलग web frameworks दोहराई गई-key के मामले को अलग तरीके से संभालते हैं, Rails और Express दोहराई गई keys को arrays में संग्रहित करते हैं, जबकि PHP बाद के मानों से पहले के मानों को overwrite करता है जब तक कि key name[] bracket convention का उपयोग न करे, जो API integrations में cross-framework bugs का निरंतर स्रोत है।
सामान्य URL-parsing जाल
- दोहरी encoding। पहले से encoded URL को encode करने पर
%2520उत्पन्न होता है (%स्वयं%25के रूप में encoded हो जाता है)। यह तब दिखाई देता है जब URLs कई परतों (frontend → backend → analytics) से होकर गुज़रती हैं और प्रत्येक परत «सहायक रूप से» एक बार और encode करती है। समाधान है पूरी तरह से नीचे तक decode करना और फिर एक बार re-encode करना। - Query strings में + vs %20।
+form-encoded query string के अंदर एक space का अर्थ रखता है लेकिन path या fragment के अंदर शाब्दिक+का अर्थ रखता है। conventions को मिलाने से कठिन-to-debug bugs उत्पन्न होते हैं जहाँ «John+Doe» query में «John Doe» बन जाता है लेकिन path में «John+Doe» के रूप में रहता है। - Case संवेदनशीलता। Host case-insensitive है (
EXAMPLE.comऔरexample.comसमान host हैं); path अधिकांश servers (Linux/Unix) पर case-sensitive है लेकिन अन्य पर case-insensitive है (default रूप से Windows IIS, macOS HFS+)। इसका मतलब है कि server के आधार पर समान URL अलग सामग्री में हल हो सकती है। - URLs में IPv6। IPv6 पतों में colons होते हैं, जो host:port separator से टकराते हैं। समाधान है IPv6 पते को वर्ग कोष्ठकों में लपेटना:
http://[2001:db8::1]:8080/path। कई URL parsers ऐतिहासिक रूप से इस पर असफल हुए; modern browsers और WHATWG parser इसे सही ढंग से संभालते हैं। - OAuth fragment tokens। OAuth 2.0 implicit grant flow URL fragment में access tokens लौटाता था (
#access_token=...) ताकि वे server logs में दिखाई न दें। आधुनिक OAuth मार्गदर्शन इस flow को PKCE के साथ authorisation code के पक्ष में हतोत्साहित करता है, लेकिन legacy systems अभी भी fragment tokens उत्सर्जित करते हैं। - Round-trip गैर-पहचान। URL को parse करना और फिर से stringify करना हमेशा मूल string उत्पन्न नहीं करता, parser सामान्यीकृत करता है (percent-encoded अनारक्षित वर्णों को decode करता है, host को lowercase करता है, कुछ implementations में query parameters को sort करता है)। यह न मानें कि
parse(url).toString() === url।
सामान्य उपयोग के मामले
- API requests को debug करना। लंबी query string वाला REST endpoint पढ़ने में कठिन है; इसे parse करने पर प्रत्येक parameter अपनी पंक्ति पर दिखता है।
- OAuth callback निरीक्षण। Auth-flow URLs encoded state, code, scope और access tokens ले जाती हैं जिन्हें server को बिना उजागर किए debugging के लिए decode करना होता है।
- Redirect chains का पता लगाना। जब एक URL कई मध्यवर्ती URLs के माध्यम से redirect होती है, प्रत्येक को parse करना श्रृंखला का अनुसरण करने और यह पहचानने में मदद करता है कि redirect कहाँ टूट रहा है।
- UTM tag लेखापरीक्षा। Analytics URLs (
?utm_source=...&utm_medium=...&utm_campaign=...) query string की दीवार के बजाय parameter-by-parameter पढ़ने में आसान हैं। - सुरक्षा लेखापरीक्षा। URL parameters में SQL injection patterns या path traversal अनुक्रमों की तलाश; parsing प्रत्येक मान को समीक्षा के लिए अलग-अलग उजागर करती है।
- Form-encoded body parsing। URL query strings में उपयोग किया जाने वाला वही format
application/x-www-form-urlencodedPOST bodies में उपयोग किया जाता है। - Deep link निरीक्षण। Mobile app deep links और web app routes path या query में जटिल अवस्था encode करते हैं; parsing संरचना को दृश्यमान बनाती है।
- Affiliate / share-link समीक्षा। Email campaigns या affiliate programmes से tracking links encoded redirect URLs और tracking IDs ले जाते हैं जो decoding से लाभान्वित होते हैं।
गोपनीयता: URLs वास्तविक रहस्य ले जाते हैं
URLs को आम तौर पर गुप्त नहीं माना जाता, लेकिन वे अक्सर ऐसा डेटा ले जाती हैं जो होता है। OAuth callback URLs में access tokens शामिल होते हैं। Magic-link login URLs में single-use authentication tokens शामिल होते हैं। Password-reset links में reset tokens शामिल होते हैं। आंतरिक API URLs में आंतरिक hostnames और routing paths शामिल होते हैं जो infrastructure का खुलासा करते हैं। यहाँ तक कि साधारण application URLs query parameters के माध्यम से उपयोगकर्ता व्यवहार का खुलासा करती हैं, search terms, filter selections, profile IDs, session identifiers। Referer header प्रत्येक linked-to site को पिछली URL leak करता है, 2017 में W3C Candidate Recommendation के रूप में पेश किए गए Referrer-Policy header द्वारा कम किया गया (browser defaults अभी भी अलग-अलग हैं)। URLs server access logs में, browser history में, browser bookmarks में, CDN logs में, analytics pipelines में, chat-app link previews में समाप्त होती हैं। एक server-side URL parser उसमें pasted प्रत्येक URL देखता है; एक browser-only parser नहीं देखता। आंतरिक API URLs, tokens के साथ OAuth callbacks, password-reset links, या कोई भी URL जिसे आप किसी अजनबी की हार्ड ड्राइव पर नकल किया हुआ नहीं देखना चाहेंगे, के लिए browser-only parser सही architecture है। parsing के दौरान DevTools के Network tab में सत्यापित करें, या लोड होने के बाद page को offline (airplane mode) ले जाएँ।
अक्सर पूछे जाने वाले प्रश्न
एक URL में कौन से भाग होते हैं?
छह वैचारिक भाग: scheme (https, http, ftp, mailto), userinfo (आधुनिक उपयोग में दुर्लभ, ज्यादातर browsers द्वारा phishing-mitigation के रूप में हटा दिया गया), host (domain या IP), port (HTTP के लिए default 80, HTTPS के लिए 443), path (slash-separated पदानुक्रम), query (? के बाद key-value जोड़े), और fragment (# के बाद, server को कभी नहीं भेजा गया)। पूरी grammar RFC 3986 §3 (जनवरी 2005, STD 66) और WHATWG URL Living Standard में है।
मैं URL-encoded वर्णों को कैसे decode करूँ?
Percent-encoding असुरक्षित वर्णों को byte के hex code के बाद % से बदलती है: एक space %20 है, एक colon %3A है, एक forward slash %2F है, एक ampersand %26 है, at-sign %40 है। UTF-8 multi-byte वर्ण byte-by-byte encoded होते हैं, इसलिए é %C3%A9 बन जाता है (दो bytes)। parser प्रदर्शित output में सभी percent-encoded वर्णों को स्वचालित रूप से decode करता है। मानक JavaScript functions हैं encodeURIComponent() individual values को encode करने के लिए और decodeURIComponent() decoding के लिए।
URL fragment क्या है?
fragment (# के बाद सब कुछ) URL का एकमात्र भाग है जो पूरी तरह से client-side संसाधित होता है, यह HTTP अनुरोधों में web server को कभी नहीं भेजा जाता। मूल उद्देश्य: उस ID वाले anchor element तक browser को scroll करना। आधुनिक उपयोगों में single-page application route अवस्था (#/dashboard/profile), OAuth implicit-flow tokens (अब PKCE के साथ authorisation code के पक्ष में हतोत्साहित), और PDF page navigation (file.pdf#page=5) शामिल हैं। चूँकि fragments server तक नहीं पहुँचते, वे ऐसे values को छिपाने का स्थान हैं जो server logs में नहीं दिखने चाहिए।
+ कभी-कभी space और कभी-कभी + क्यों होता है?
दो encoding परंपराएँ मौजूद हैं। application/x-www-form-urlencoded (default HTML form submission format) spaces को + के रूप में encode करता है; standard percent-encoding (RFC 3986 के अनुसार) spaces को %20 के रूप में encode करता है। दोनों query strings में मान्य हैं; केवल %20 paths और fragments में मान्य है। URLSearchParams दोनों को पारदर्शी रूप से संभालता है। cross-context bug तब उत्पन्न होता है जब code encodeURIComponent (जो space को %20 के रूप में encode करता है) का उपयोग ऐसे query parameters के लिए करता है जिनकी server form-encoded रूप में अपेक्षा करता है, या इसके विपरीत।
क्या यह relative URLs को संभालता है?
Parser scheme के साथ पूर्ण URL की अपेक्षा करता है। /api/users जैसे relative path के लिए, इसे parse करने के लिए एक base URL (https://example.com/api/users) के सामने जोड़ें। कुछ relative-URL parsing (browser के href attributes के लिए जिस तरह से करता है उसी तरह base URL के विरुद्ध हल करना) roadmap पर है, WHATWG URL constructor का दो-argument रूप (new URL(relative, base)) इसे संभालता है और यह वह है जिसका production code को उपयोग करना चाहिए।
क्या मेरी URLs कहीं भेजी जाती हैं?
नहीं। Parsing पूरी तरह से आपके browser में WHATWG URL constructor के माध्यम से चलता है, आपके द्वारा pasted की गई URL कभी आपके device को नहीं छोड़ती। Parse पर click करते समय DevTools के Network tab में सत्यापित करें, या लोड होने के बाद page को offline (airplane mode) ले जाएँ। access tokens वाली OAuth callback URLs, single-use tokens वाले password-reset links, infrastructure का खुलासा करने वाली आंतरिक API URLs, या कोई भी URL जिसे आप किसी अजनबी की हार्ड ड्राइव पर नकल किया हुआ नहीं देखना चाहते, के लिए सुरक्षित।