it-swarm.com.de

Abrufen einer absoluten URL von einer relativen. (IE6 Problem)

Ich verwende derzeit die folgende Funktion, um eine relative URL in eine absolute umzuwandeln:

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

Dies funktioniert in den meisten Browsern recht gut, aber der IE6 besteht immer noch darauf, die relative URL zurückzugeben! Dasselbe gilt, wenn ich getAttribute ('href') verwende.

Die einzige Möglichkeit, eine qualifizierte URL aus IE6 zu erhalten, besteht darin, ein img-Element zu erstellen und das Attribut 'src' abzufragen. Das Problem besteht darin, dass eine Serveranforderung generiert wird. etwas, das ich vermeiden möchte.

Meine Frage lautet also: Gibt es eine Möglichkeit, eine vollqualifizierte URL in IE6 von einer relativen URL abzurufen (ohne eine Serveranforderung)?


Bevor Sie eine schnelle Regex-/String-Korrektur empfehlen, versichere ich Ihnen, dass dies nicht so einfach ist. Basiselemente + relative URLs mit doppelter Periode + eine Tonne andere potenzielle Variablen machen es wirklich zur Hölle!

Es muss eine Möglichkeit geben, dies zu tun, ohne ein Mammut einer regulären Lösung zu schaffen.

79
James

Wie seltsam! IE versteht es jedoch, wenn Sie innerHTML anstelle von DOM-Methoden verwenden.

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;
}

Ein bisschen hässlich, aber prägnanter als es selbst zu tun.

47
bobince

Solange der Browser das <base> -Tag korrekt implementiert, neigen die Browser dazu:

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;
}

Hier ist eine jsfiddle, mit der Sie experimentieren können: http://jsfiddle.net/ecmanaut/RHdnZ/

27
ecmanaut

Sie können es auf IE6 zum Laufen bringen, indem Sie das Element klonen:

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

(Getestet mit IETester in den Modi IE6 und IE5.5)

16
Oriol

Ich fand auf diesem Blog eine andere Methode, die wirklich wie @ Bobince-Lösung aussieht.

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;
}

Ich fand es ein bisschen eleganter, keine große Sache.

10

RI.js scheint das Problem zu lösen:

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

Siehe auch http://medialize.github.io/URI.js/docs.html#absoluteto

Nicht mit IE6 getestet, aber möglicherweise hilfreich für andere, die nach dem allgemeinen Problem suchen.

7
koppor

Eigentlich wollte ich einen Ansatz, der keine Änderung des Originaldokuments (auch nicht vorübergehend) erfordert, aber dennoch das integrierte URL-Parsing des Browsers und dergleichen verwendet. Außerdem wollte ich in der Lage sein, meine eigene Basis bereitzustellen (wie die Antwort von ecmanaught). Es ist ziemlich einfach, verwendet aber createHTMLDocument (könnte durch createDocument ersetzt werden, um möglicherweise ein bisschen kompatibler zu sein):

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/

7
Chris Hopman

Diese Lösung funktioniert in allen Browsern.

/**
 * 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

Relative URLs mit "..", wie "../file.png", werden jedoch nicht unterstützt.

5
Feross

Dies ist die Funktion, die ich verwende, um grundlegende relative URLs aufzulösen:

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(/^\.\//, '');
}

Testen Sie es auf jsfiddle: https://jsfiddle.net/n11rg255/

Es funktioniert sowohl im Browser als auch in node.js oder anderen Umgebungen.

3
lovasoa

Ich habe diesen Blog-Beitrag gefunden, der die Verwendung eines Bildelements anstelle eines Ankers vorschlägt:

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

Das funktioniert, um eine URL auch in IE6 zuverlässig zu erweitern. Das Problem ist jedoch, dass die von mir getesteten Browser die Ressource beim Festlegen des image src-Attributs sofort herunterladen - auch wenn Sie in der nächsten Zeile den src-Wert auf null setzen.

Ich werde stattdessen Bobince's Lösung ausprobieren.

2
Jesse Hallett

Wenn url nicht mit '/' beginnt

Nehmen Sie die URL der aktuellen Seite und hacken Sie alles ab, was nach dem letzten '/' liegt. Fügen Sie dann die relative URL hinzu.

Sonst wenn url mit '/' beginnt

Nehmen Sie die URL der aktuellen Seite und hacken Sie alles rechts neben dem einzelnen '/' ab. dann hänge die url an.

Sonst wenn url mit # oder? Beginnt

Nimm die URL der aktuellen Seite und hänge einfach url an


Ich hoffe, es funktioniert für Sie

0
geowa4