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.
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.
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/
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)
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.
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.
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;
}
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.
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.
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.
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