किसी रिश्तेदार से पूर्ण URL प्राप्त करना। (IE6 मुद्दा)


80

मैं वर्तमान में एक रिश्तेदार URL को पूर्ण रूप में बदलने के लिए निम्नलिखित फ़ंक्शन का उपयोग कर रहा हूं:

function qualifyURL(url) {
    var a = document.createElement('a');
    a.href = url;
    return a.href;
}

यह अधिकांश ब्राउज़रों में काफी अच्छा काम करता है लेकिन IE6 रिश्तेदार URL को वापस करने पर जोर देता है! अगर मैं getAttribute ('href') का उपयोग करता हूं तो यह वही करता है।

जिस तरह से मैं IE6 से एक योग्य URL प्राप्त करने में सक्षम हूं, वह एक img तत्व और क्वेरी 'src' विशेषता बनाने के लिए है - इसके साथ समस्या यह है कि यह एक सर्वर अनुरोध उत्पन्न करता है; कुछ मैं बचना चाहता हूँ।

तो मेरा सवाल यह है: क्या IE6 में किसी रिश्तेदार से (सर्वर अनुरोध के बिना) पूरी तरह से योग्य URL प्राप्त करने का कोई तरीका है?


इससे पहले कि आप एक त्वरित regex / string को ठीक करने की सलाह दें, मुझे विश्वास है कि यह इतना आसान नहीं है। आधार तत्व + दोहरी अवधि सापेक्ष url + अन्य संभावित चर का एक टन वास्तव में इसे नरक बनाते हैं!

रेगेक्स’य समाधान का मैमथ बनाए बिना इसे करने का एक तरीका होना चाहिए ??


1
आप सापेक्ष URI को पूर्ण रूप से हल करने के लिए js-uri का उपयोग कर सकते हैं ।
गंबूबो

शुक्रिया गुम्बो, मुझे लगता है कि यह करना होगा। मुझे एक अधिक संक्षिप्त समाधान पसंद आया होगा, लेकिन फिर भी धन्यवाद, मुझे यह कभी नहीं पता था कि यह js-uri वर्ग अस्तित्व में है!
जेम्स

8
मीठी हैक! IE6 के बारे में परवाह नहीं है। मुझे घंटों बचाया। आपने धमाल मचाया।
टॉम हैरिसन

मुझे इसके साथ काम नहीं मिला, मेरे पास "फू" है और मुझे " example.com/foo " चाहिए
Jaime Hablutzel

Js-uri लाइब्रेरी को वह नहीं लगता जो मूल पोस्टर चाहता है।
djsmith

जवाबों:


47

कितना अजीब है! IE, हालांकि, इसे समझें जब आप DOM तरीकों के बजाय आंतरिक HTML का उपयोग करते हैं।

function escapeHTML(s) {
    return s.split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
}
function qualifyURL(url) {
    var el= document.createElement('div');
    el.innerHTML= '<a href="'+escapeHTML(url)+'">x</a>';
    return el.firstChild.href;
}

थोड़ा बदसूरत, लेकिन खुद को करने की तुलना में अधिक संक्षिप्त।


मुझे इस तरह का समाधान एक ऐसे ब्लॉग पर मिला, जिसे भागने के लिए कोड की आवश्यकता नहीं है: stackoverflow.com/a/22918332/82609
सेबस्टियन लॉबर

HTML दृष्टिकोण के अनुसार, यह दृष्टिकोण null (U + 0000) को ull (U + FFFD) से बदल देता है ।
ओरोल

26

जब तक ब्राउज़र सही ढंग से <आधार> टैग को लागू करता है, तब तक ब्राउज़र निम्न होते हैं:

function resolve(url, base_url) {
  var doc      = document
    , old_base = doc.getElementsByTagName('base')[0]
    , old_href = old_base && old_base.href
    , doc_head = doc.head || doc.getElementsByTagName('head')[0]
    , our_base = old_base || doc_head.appendChild(doc.createElement('base'))
    , resolver = doc.createElement('a')
    , resolved_url
    ;
  our_base.href = base_url || '';
  resolver.href = url;
  resolved_url  = resolver.href; // browser magic at work here

  if (old_base) old_base.href = old_href;
  else doc_head.removeChild(our_base);
  return resolved_url;
}

यहाँ एक jsfiddle है जहाँ आप इसके साथ प्रयोग कर सकते हैं: http://jsfiddle.net/ecmanaut/RHdnZZ/


यह पार्टी के लिए तीन साल की देरी है, इसलिए इसे मार्केटिंग या बहुत सारे लोगों को मुद्दा बनाए रखने और कोड-रूढ़िवादी और सटीक समाधान के बिना शीर्ष पर उठने में थोड़ी देर लगेगी।
ecmanaut

2
मनमाना आधार URL का समर्थन करने के अलावा, यह प्रश्न में प्रस्तुत समाधान से बिल्कुल अलग कैसे है? यह IE 6 पर काम करता है?
जॉन

1
@ AoodleusDrZaius नहीं चाहिए, लेकिन वे हो सकते हैं यदि आप चाहें। जावास्क्रिप्ट केवल एक पंक्ति के अंत में ऑटो अर्धविराम जोड़ता है जब ऐसा करने से आगामी पंक्ति एक अमान्य कथन नहीं होगी। ", foo = 1" एक वाक्यविन्यास त्रुटि है, और इस प्रकार पूरे संस्करण विवरण का मूल्यांकन थोक, सेन्स सिसोलिक प्रविष्टि में किया जाता है।
एकमान

2
@AndreasDietrich यह इसलिए है क्योंकि आप किसी भी तर्क को base_urlपैरामीटर के पास नहीं भेजते हैं , इसलिए यह बन जाता है undefinedऔर इसे कठोर कर दिया जाता है "undefined"। आपको इसके बजाय खाली स्ट्रिंग पास करनी चाहिए। या, यदि आप 2nd पैरामीटर को वैकल्पिक बनाना चाहते हैं, तो our_base.href = base_url || ""इसके बजाय our_base.href = base_url..
Oriol

1
अच्छा विचार, @ ऑरिओल - दोनों मापदंडों को पारित नहीं करने वाले लोगों के लिए मित्रवत डिफ़ॉल्ट व्यवहार नहीं करने का कोई कारण नहीं है। को एकीकृत।
इकोमानोट

16

आप IE6 पर काम कर सकते हैं बस तत्व क्लोनिंग:

function qualifyURL(url) {
    var a = document.createElement('a');
    a.href = url;
    return a.cloneNode(false).href;
}

(IE6 और IE5.5 मोड पर IETester का उपयोग करके परीक्षण किया गया)


10

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

function canonicalize(url) {
    var div = document.createElement('div');
    div.innerHTML = "<a></a>";
    div.firstChild.href = url; // Ensures that the href is properly escaped
    div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser
    return div.firstChild.href;
}

मुझे यह थोड़ा अधिक सुरुचिपूर्ण लगा, बड़ी बात नहीं।


7

URI.js समस्या को हल करने के लिए लगता है:

URI("../foobar.html").absoluteTo("http://example.org/hello/world.html").toString()

यह सभी देखें Http://medialize.github.io/URI.js/docs.html#absoluteto

IE6 के साथ परीक्षण नहीं, लेकिन शायद सामान्य मुद्दे पर खोज करने वाले अन्य लोगों के लिए उपयोगी है।


1
चीजों के नोड पक्ष पर (क्रॉलिंग आदि के लिए), सही लाइब्रेरी यहां उपलब्ध है npm install URIjs, अन्य पुस्तकालय द्वारा समान नाम से नहीं
y3sh

npm पैकेज का नाम बदलकर urijs github.com/medialize/URI.js#use-urijs
डैनियल लिज़िक

7

मैं वास्तव में इसके लिए एक दृष्टिकोण चाहता था जिसे मूल दस्तावेज़ को संशोधित करने की आवश्यकता नहीं थी (अस्थायी रूप से भी नहीं) लेकिन फिर भी ब्राउज़र के बेसिन यूआरएल पार्सिंग और इस तरह का उपयोग किया। इसके अलावा, मैं अपना स्वयं का आधार प्रदान करने में सक्षम होना चाहता था (जैसे कि परमानंद का उत्तर)। यह सीधा है, लेकिन createHTMLDocument का उपयोग करता है (संभवतः थोड़ा अधिक संगत होने के लिए createDocument के साथ प्रतिस्थापित किया जा सकता है):

function absolutize(base, url) {
    d = document.implementation.createHTMLDocument();
    b = d.createElement('base');
    d.head.appendChild(b);
    a = d.createElement('a');
    d.body.appendChild(a);
    b.href = base;
    a.href = url;
    return a.href;
}

http://jsfiddle.net/5u6j403k/


1
यकीन नहीं होता कि मुझे कुछ याद आ रहा है, लेकिन IE6 (न ही 7, 8) का समर्थन नहीं करता हैdocument.implementation.createHTMLDocument
Oriol

मैंने इसका उपयोग तब किया जब मैं अन्य पृष्ठों को लोड और परिमार्जन करने के लिए एक वेब ऐप का उपयोग कर रहा था। JQuery.load से कॉलबैक $("#loadedHere").createElement("a").url="foo"में, एक रिक्त यूआरएल के परिणामस्वरूप मुझे एक अलग डॉक्टर बनाने का सहारा लेना पड़ा।
एरिक

5

यह समाधान सभी ब्राउज़रों में काम करता है।

/**
 * Given a filename for a static resource, returns the resource's absolute
 * URL. Supports file paths with or without origin/protocol.
 */
function toAbsoluteURL (url) {
  // Handle absolute URLs (with protocol-relative prefix)
  // Example: //domain.com/file.png
  if (url.search(/^\/\//) != -1) {
    return window.location.protocol + url
  }

  // Handle absolute URLs (with explicit origin)
  // Example: http://domain.com/file.png
  if (url.search(/:\/\//) != -1) {
    return url
  }

  // Handle absolute URLs (without explicit origin)
  // Example: /file.png
  if (url.search(/^\//) != -1) {
    return window.location.origin + url
  }

  // Handle relative URLs
  // Example: file.png
  var base = window.location.href.match(/(.*\/)/)[0]
  return base + url

हालांकि, यह "../file.png" जैसे ".." वाले सापेक्ष URL का समर्थन नहीं करता है।


इससे कुछ समस्याएं हैं। उदाहरण के लिए, आप मान रहे हैं कि आधार विंडोज़ के समान है और मुझे नहीं लगता कि यह काम करता है यदि मेरे पास url में url param है। कहते हैं /img/profile.php?url=https://google.com/logo.svg
तोडोर्स

3

यह वह फ़ंक्शन है जिसका उपयोग मैं मूल सापेक्ष URL को हल करने के लिए करता हूं:

function resolveRelative(path, base) {
    // Absolute URL
    if (path.match(/^[a-z]*:\/\//)) {
      return path;
    }
    // Protocol relative URL
    if (path.indexOf("//") === 0) {
      return base.replace(/\/\/.*/, path)
    }
    // Upper directory
    if (path.indexOf("../") === 0) {
        return resolveRelative(path.slice(3), base.replace(/\/[^\/]*$/, ''));
    }
    // Relative to the root
    if (path.indexOf('/') === 0) {
        var match = base.match(/(\w*:\/\/)?[^\/]*\//) || [base];
        return match[0] + path.slice(1);
    }
    //relative to the current directory
    return base.replace(/\/[^\/]*$/, "") + '/' + path.replace(/^\.\//, '');
}

इसे jsfiddle पर टेस्ट करें: देखें https://jsfiddle.net/n11rg255/

यह ब्राउजर और नोड.जेएस या अन्य वातावरण दोनों में काम करता है।


2

मुझे यह ब्लॉग पोस्ट मिला जो एक एंकर के बजाय एक छवि तत्व का उपयोग करने का सुझाव देता है:

http://james.padolsey.com/javascript/getting-a-fully-qualified-url/

IE6 में भी, URL का मज़बूती से विस्तार करने के लिए काम करता है। लेकिन समस्या यह है कि मैंने जिन ब्राउज़रों का परीक्षण किया है, वे छवि src विशेषता को स्थापित करने पर तुरंत संसाधन डाउनलोड करेंगे - भले ही आप src को अगली पंक्ति पर शून्य करने के लिए सेट करें।

मैं इसके बजाय बॉबिन के समाधान को एक रास्ता देने जा रहा हूं।


0

अगर url '/' से शुरू नहीं होता है

वर्तमान पृष्ठ का url लें, पिछले '/' के अलावा सब कुछ काट लें; फिर रिश्तेदार url संलग्न करें।

यदि url'/ ’से शुरू होता है

वर्तमान पृष्ठ का url लें और सब कुछ एकल '/' के दाईं ओर काटें; फिर url संलग्न करें।

और अगर url# के साथ शुरू होता है?

वर्तमान पृष्ठ का url लें और बस संलग्न करें url


आशा है कि यह आप के लिए काम करता है


2
आप भूल गए कि URL "//" से शुरू हो सकते हैं, जो उन्हें योजना-सापेक्ष बनाता है। //foo.com/bar/
स्कॉट वोलचोक

1
आप भी डॉटेड रिलेटेड भूल गए ../../ सिंटैक्स (क्या यह चूक मायने रखती है या नहीं यह इस बात पर निर्भर करता है कि आउटपुट के लिए क्या आवश्यक है)
हॉलवेर्स

-1

यदि यह ब्राउज़र में चलता है, तो मेरे लिए इस तरह का काम करता है ।।

  function resolveURL(url, base){
    if(/^https?:/.test(url))return url; // url is absolute
    // let's try a simple hack..
    var basea=document.createElement('a'), urla=document.createElement('a');
    basea.href=base, urla.href=url;
    urla.protocol=basea.protocol;// "inherit" the base's protocol and hostname
    if(!/^\/\//.test(url))urla.hostname=basea.hostname; //..hostname only if url is not protocol-relative  though
    if( /^\//.test(url) )return urla.href; // url starts with /, we're done
    var urlparts=url.split(/\//); // create arrays for the url and base directory paths
    var baseparts=basea.pathname.split(/\//); 
    if( ! /\/$/.test(base) )baseparts.pop(); // if base has a file name after last /, pop it off
    while( urlparts[0]=='..' ){baseparts.pop();urlparts.shift();} // remove .. parts from url and corresponding directory levels from base
    urla.pathname=baseparts.join('/')+'/'+urlparts.join('/');
    return urla.href;
  }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.