from - open url new window javascript
Obtener una URL absoluta de una relativa.(Problema IE6) (11)
Actualmente estoy usando la siguiente función para ''convertir'' una URL relativa a 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 pude obtener un URL calificado de IE6 es crear un elemento img y consultar su atributo ''src''; el problema 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 de servidor)?
Antes de recomendar una reparación rápida de expresiones regulares / cadenas, le aseguro que no es tan simple. Elementos base + urls relativas de período doble + una tonelada de otras variables potenciales realmente lo convierten en el infierno!
Debe haber una forma de hacerlo sin tener que crear un mamut de una solución regular?
¡Que extraño! IE lo entiende, sin embargo, cuando usas 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 Doing It Yourself.
De hecho, quería un enfoque para esto que no requiriera modificar el documento original (ni siquiera temporalmente) pero aún así usar el análisis url incorporado del navegador y tal. Además, quería poder proporcionar mi propia base (como la respuesta de ecmanaught). Es bastante sencillo, pero usa createHTMLDocument (podría ser reemplazado por createDocument para ser un poco más compatible):
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;
}
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 es gran cosa.
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 de manera confiable una URL, incluso en IE6. Pero el problema es que los navegadores que he probado descargarán inmediatamente el recurso al configurar el atributo src de la imagen, incluso si configuras el src como nulo en la siguiente línea.
Voy a darle una solución de Bobince en su lugar.
Esta es la función que uso para resolver URLs básicas relativas:
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.
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".
Puedes 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 usando IETester en modos IE6 e IE5.5)
Si se ejecuta en el navegador, este tipo de trabajo me funciona ...
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;
}
Siempre que el navegador implemente correctamente la etiqueta <base>, los 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 puedes experimentar con él: http://jsfiddle.net/ecmanaut/RHdnZ/
URI.js parece resolver el problema:
URI("../foobar.html").absoluteTo("http://example.org/hello/world.html").toString()
Ver también http://medialize.github.io/URI.js/docs.html#absoluteto
No se ha verificado con IE6, pero puede ser útil para otros que buscan el problema general.
Si url
no comienza con ''/''
Toma la url de la página actual, corta todo lo que haya pasado el último ''/''; luego añada la URL relativa.
De lo contrario, si url
comienza con ''/''
Tome la url de la página actual y recorte todo a la derecha del único ''/''; luego añada la url.
De lo contrario, si la url
comienza con # o?
Tome la URL de la página actual y simplemente agregue la url
Espero que funcione para ti