हम यहां हनीबैगर में एक मील के पत्थर तक पहुंचे हैं। हमारे बिक्री पृष्ठ अब हमारे मुख्य रेल ऐप का हिस्सा नहीं हैं। यह वर्षों से मेरी इच्छा सूची में है, लेकिन बिल्कुल सर्वोच्च प्राथमिकता नहीं है।
इस माइग्रेशन के हिस्से के रूप में, मैंने खुद को URI.join
. का उपयोग करते हुए पाया विशेष रीडायरेक्ट लिंक बनाने के लिए। लेकिन मैं जल्दी से एक समस्या में पड़ गया। URI.join
मेरी अपेक्षा के अनुरूप व्यवहार नहीं कर रहा था।
मुझे उम्मीद थी कि यह पथ के टुकड़ों का एक गुच्छा लेगा और उन्हें इस तरह एक साथ स्ट्रिंग करेगा:
# This is what I was expecting. It didn't happen.
URI.join("https://www.honeybadger.io", "plans", "change")
=> "https://www.honeybadger.io/plans/change"
क्या join
किया गया तरीका बहुत अजनबी है। इसने मेरे पथ के टुकड़ों में से एक को गिरा दिया, केवल पिछले वाले, "परिवर्तन" का उपयोग करते हुए।
# This is what happened.
URI.join("https://www.honeybadger.io", "plans", "change")
=> "https://www.honeybadger.io/change"
तो यह इस तरह काम क्यों करता है?
गलतफहमी
यह पता चला है कि मैं उम्मीद कर रहा था URI.join
Array#join
. के विशेष संस्करण के समान व्यवहार करने के लिए , URL अंशों को लेना और उन्हें एक संपूर्ण URL बनाने के लिए संयोजित करना।
ऐसा नहीं है कि यह क्या करता है। बड़ा आश्चर्य।
अगर हम join
. पर एक नज़र डालें विधि का कोड, हम देखते हैं कि यह केवल सभी तर्कों पर पुनरावृति करता है, और कॉल करता है merge
प्रत्येक पर।
# File uri/rfc2396_parser.rb, line 236
def join(*uris)
uris[0] = convert_to_uri(uris[0])
uris.inject :merge
end
मर्ज विधि दो काम करती है:
- यह आपकी स्ट्रिंग जैसे "पेज" को एक सापेक्ष यूआरआई ऑब्जेक्ट में परिवर्तित करता है।
- यह आधार यूआरआई पर सापेक्ष यूआरआई को हल करने का प्रयास करता है। यह ठीक उसी तरह से करता है जैसे RFC2396, खंड 5.2 में निर्दिष्ट है।
तो यह अच्छा है, लेकिन यह मेरे द्वारा पहले बताए गए अप्रत्याशित व्यवहार की व्याख्या कैसे करता है?
URI.join("https://www.honeybadger.io", "plans", "change")
=> "https://www.honeybadger.io/change"
आइए इसके माध्यम से कदम उठाएं। उपरोक्त कोड इसके बराबर है:
URI.parse("https://www.honeybadger.io/plans").merge("change")
उपरोक्त कोड सापेक्ष यूआरआई को हल करने का प्रयास करता है, पूर्ण यूआरआई "https://www.honeybadger.io/plans" के विरुद्ध "बदलें"।
ऐसा करने के लिए, यह RFC2396, धारा 5.2.6 का अनुसरण करता है, जिसमें कहा गया है:
<ब्लॉकक्वॉट>ए) आधार यूआरआई के पथ घटक के अंतिम खंड को छोड़कर सभी को बफर में कॉपी किया गया है। दूसरे शब्दों में, अंतिम (दाएं-सबसे) स्लैश वर्ण के बाद कोई भी वर्ण, यदि कोई हो, बाहर रखा गया है।
बी) संदर्भ का पथ घटक बफर स्ट्रिंग में जोड़ा जाता है।
आइए साथ खेलें:
- पूर्ण URL के अंतिम खंड को छोड़कर सब कुछ कॉपी करें। यह मुझे देता है
"https://www.honeybadger.io/"
- सापेक्ष पथ जोड़ें, जिसके परिणामस्वरूप
"https://www.honeybadger.io/change"
दुनिया फिर से समझ में आती है!
निष्कर्ष
जबकि URI.join
विभिन्न पथ खंडों से यूआरएल बनाने के लिए इस्तेमाल किया जा सकता है, यह वास्तव में ऐसा नहीं है जिसे इसे करने के लिए डिज़ाइन किया गया है। इसे कुछ अधिक जटिल करने के लिए डिज़ाइन किया गया है:RFC में निर्दिष्ट मानकों के अनुसार URI को पुनरावर्ती रूप से मर्ज करें।
जहां तक मेरे निजी प्रोजेक्ट का सवाल है - हमारे नए बिक्री पृष्ठों पर रीडायरेक्ट में उपयोग करने के लिए URL बनाना - ठीक है, मैंने इसके बजाय Array#join का उपयोग किया है। :)पी>
संपादित करें 8/12/2016: इस लेख को प्रकाशित करने के बाद मुझे कुछ ट्वीट्स प्राप्त हुए जिनमें सुझाव दिया गया कि मैं File.join
. का उपयोग करता हूं इस काम के लिए। इसका डबल स्लैश से बचने का लाभ है, अर्थात। /my//path
लेकिन विंडोज़ जैसे ओएस पर टूट जाएगा, जहां पथ विभाजक फॉरवर्ड-स्लैश नहीं है।