Actualmente estoy usando la siguiente función para 'convertir' una URL relativa en una absoluta:
function qualifyURL(url) {
var a = document.createElement('a');
a.href = url;
return a.href;
}
Esto funciona bastante bien en la mayoría de los navegadores, pero IE6 insiste en devolver la URL relativa. Hace lo mismo si uso getAttribute ('href').
La única forma en que he podido obtener una URL calificada de IE6 es crear un elemento img y consultar su atributo 'src'; el problema con esto es que genera una solicitud de servidor; algo que quiero evitar.
Entonces, mi pregunta es: ¿Hay alguna forma de obtener una URL completamente calificada en IE6 de una relativa (sin una solicitud del servidor)?
Antes de recomendar una corrección rápida de expresiones regulares / cadenas, le aseguro que no es tan simple. ¡Los elementos base + URL relativas de doble período + una tonelada de otras variables potenciales realmente lo hacen un infierno!
¿Debe haber una manera de hacerlo sin tener que crear una gigantesca solución de expresiones regulares?
Respuestas:
¡Que extraño! IE, sin embargo, lo entiende cuando usa innerHTML en lugar de métodos DOM.
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; }
Un poco feo, pero más conciso que Hágalo usted mismo.
fuente
Siempre que el navegador implemente la etiqueta <base> correctamente, qué navegadores tienden a:
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; }
Aquí hay un jsfiddle donde puede experimentar con él: http://jsfiddle.net/ecmanaut/RHdnZ/
fuente
base_url
parámetro, por lo que se convierte enundefined
y se encadena a"undefined"
. En su lugar, deberías pasar la cadena vacía. O, si desea que el segundo parámetro sea opcional, utilice enour_base.href = base_url || ""
lugar deour_base.href = base_url
..Puede hacer que funcione en IE6 simplemente clonando el elemento:
function qualifyURL(url) { var a = document.createElement('a'); a.href = url; return a.cloneNode(false).href; }
(Probado con IETester en los modos IE6 e IE5.5)
fuente
Encontré en este blog otro método que realmente se parece a la solución @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; }
Lo encontré un poco más elegante, no gran cosa.
fuente
URI.js parece resolver el problema:
URI("../foobar.html").absoluteTo("http://example.org/hello/world.html").toString()
Véase también http://medialize.github.io/URI.js/docs.html#absoluteto
No probado con IE6, pero tal vez sea útil para otros que busquen el problema general.
fuente
npm install URIjs
, no la otra biblioteca con un nombre similarurijs
github.com/medialize/URI.js#using-urijsDe hecho, quería un enfoque para esto que no requiriera modificar el documento original (ni siquiera temporalmente) pero aún usaba el análisis de URL incorporado del navegador y demás. Además, quería poder proporcionar mi propia base (como la respuesta de ecmanaught). Es bastante sencillo, pero usa createHTMLDocument (podría reemplazarse con createDocument para ser un poco más compatible posiblemente):
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/
fuente
document.implementation.createHTMLDocument
$("#loadedHere").createElement("a").url="foo"
resultó en una URL vacía, así que tuve que recurrir a la creación de un documento separado.Esta solución funciona en todos los navegadores.
/** * 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
Sin embargo, no admite URL relativas con ".." en ellas, como "../file.png".
fuente
/img/profile.php?url=https://google.com/logo.svg
.Esta es la función que uso para resolver URL relativas básicas:
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(/^\.\//, ''); }
Pruébelo en jsfiddle: https://jsfiddle.net/n11rg255/
Funciona tanto en el navegador como en node.js u otros entornos.
fuente
Encontré esta publicación de blog que sugiere usar un elemento de imagen en lugar de un ancla:
http://james.padolsey.com/javascript/getting-a-fully-qualified-url/
Eso funciona para expandir una URL de manera confiable, incluso en IE6. Pero el problema es que los navegadores que he probado descargarán inmediatamente el recurso al configurar el atributo image src, incluso si configura src en nulo en la siguiente línea.
En su lugar, voy a probar la solución de bobince.
fuente
Si
url
no comienza con '/'Tome la URL de la página actual, elimine todo lo que pase de la última '/'; luego agregue la URL relativa.
De lo contrario, si
url
comienza con '/'Toma la URL de la página actual y corta todo a la derecha del sencillo '/'; luego agregue la URL.
De lo contrario, si
url
comienza con # o?Tome la URL de la página actual y simplemente agregue
url
Espero que funcione para ti
fuente
Si se ejecuta en el navegador, esto funciona para mí.
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; }
fuente