Ich verwende derzeit die folgende Funktion, um eine relative URL in eine absolute zu konvertieren:
function qualifyURL(url) {
var a = document.createElement('a');
a.href = url;
return a.href;
}
Dies funktioniert in den meisten Browsern recht gut, aber IE6 besteht darauf, die relative URL trotzdem zurückzugeben! Das gleiche 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 dabei ist, dass eine Serveranforderung generiert wird. etwas, das ich vermeiden möchte.
Meine Frage lautet also: Gibt es eine Möglichkeit, eine vollständig qualifizierte URL in IE6 von einer relativen URL (ohne Serveranforderung) abzurufen?
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 anderer potenzieller Variablen machen es wirklich zur Hölle!
Es muss einen Weg geben, dies zu tun, ohne ein Mammut einer Regex'y-Lösung erstellen zu müssen?
Antworten:
Wie seltsam! IE versteht es jedoch, wenn Sie innerHTML anstelle von DOM-Methoden verwenden.
function escapeHTML(s) { return s.split('&').join('&').split('<').join('<').split('"').join('"'); } 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.
quelle
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/
quelle
base_url
Parameter kein Argument übergeben , sodass er zu einemundefined
String wird"undefined"
. Sie sollten stattdessen die leere Zeichenfolge übergeben. Oder, wenn Sie den 2. Parameter optional machen möchten, verwenden Sieour_base.href = base_url || ""
anstelle vonour_base.href = base_url
..Sie können es auf IE6 zum Laufen bringen, indem Sie einfach das Element klonen:
function qualifyURL(url) { var a = document.createElement('a'); a.href = url; return a.cloneNode(false).href; }
(Getestet mit IETester im IE6- und IE5.5-Modus)
quelle
Ich habe in diesem Blog eine andere Methode gefunden, die wirklich wie eine @ bbince-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 etwas eleganter, keine große Sache.
quelle
URI.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.
quelle
npm install URIjs
, nicht die andere Bibliothek mit ähnlichem Namenurijs
github.com/medialize/URI.js#using-urijsEigentlich wollte ich einen Ansatz, der keine Änderung des Originaldokuments (nicht einmal vorübergehend) erfordert, aber dennoch die integrierte URL-Analyse 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/
quelle
document.implementation.createHTMLDocument
$("#loadedHere").createElement("a").url="foo"
führte zu einer leeren URL, sodass ich ein separates Dokument erstellen musste.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.
quelle
/img/profile.php?url=https://google.com/logo.svg
.Dies ist die Funktion, mit der ich grundlegende relative URLs auflöse:
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.
quelle
Ich habe diesen Blog-Beitrag gefunden, in dem vorgeschlagen wird, ein Bildelement anstelle eines Ankers zu verwenden:
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 Attributs image src sofort herunterladen - selbst wenn Sie den src in der nächsten Zeile auf null setzen.
Ich werde stattdessen Bobince's Lösung ausprobieren.
quelle
Wenn
url
nicht mit '/' beginntNehmen Sie die URL der aktuellen Seite und hacken Sie alles nach dem letzten '/' ab. Fügen Sie dann die relative URL hinzu.
Sonst, wenn
url
mit '/' beginntNehmen Sie die URL der aktuellen Seite und hacken Sie alles rechts von der Single '/' ab. Fügen Sie dann die URL hinzu.
Sonst wenn
url
mit # oder beginnt?Nehmen Sie die URL der aktuellen Seite und fügen Sie sie einfach hinzu
url
Hoffe es funktioniert bei dir
quelle
Wenn es im Browser läuft, funktioniert diese Art von für mich ..
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; }
quelle