从相对的url获取绝对url。 (IE6问题)

我目前正在使用以下函数将相对URL“转换”为绝对URL:

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

这在大多数浏览器中工作得很好,但是IE6仍然坚持返回相对URL! 如果我使用getAttribute('href'),它也是一样的。

我唯一能够从IE6获得合格的URL的方法是创build一个img元素并查询它的'src'属性 – 这个问题是它产生了一个服务器请求; 我想避免的事情。

所以我的问题是:有没有办法从相对的(没有服务器请求)在IE6中获得完全合格的URL?


在你推荐一个快速的正则expression式/string修复之前,我向你保证并不那么简单。 基本元素+双周期相对URL +一吨其他潜在variables真的让它地狱!

必须有办法做到这一点,而不必创造一个正则expression式解决scheme的庞然大物?

多么奇怪! 然而,IE使用innerHTML而不是DOM方法来理解它。

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

有点丑,但比自己做更简洁。

只要浏览器正确地实现<base>标签,哪些浏览器倾向于:

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

这里是一个jsfiddle你可以尝试它: http : //jsfiddle.net/ecmanaut/RHdnZ/

你可以使它在IE6上工作,只是克隆元素:

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

(在IE6和IE5.5模式下使用IETestertesting)

我在这个博客上发现了另外一种看起来像@ bobince解决scheme的方法。

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

我发现它更优雅一点,不是什么大不了的。

URI.js似乎解决了这个问题:

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

另见http://medialize.github.io/URI.js/docs.html#absoluteto

没有IE6的testing,但可能有助于其他人寻找一般问题。

我其实想要一个这样的方法,不需要修改原始文件(甚至暂时),但仍然使用浏览器的内置urlparsing等。 另外,我想能够提供我自己的基础(如ecmanaught的答案)。 这很简单,但是使用createHTMLDocument(可以用createDocument代替,可能会更加兼容):

 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/

此解决scheme适用于所有浏览器。

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

但是,它不支持“..”的相对URL,比如“../file.png”。

这是我用来parsing基本相对URL的函数:

 function resolveRelative(path, base) { // Absolute URL if (path.match(/^[az]*:\/\//)) { 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(/^\.\//, ''); } 

在jsfiddle上testing它: https ://jsfiddle.net/n11rg255/

它可以在浏览器和node.js或其他环境中使用。

我发现这个博客文章,build议使用图像元素,而不是一个锚:

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

即使在IE6中,这也可以可靠地扩展URL。 但问题是,我testing过的浏览器会立即下载资源设置图像的src属性 – 即使您将src设置为null在下一行。

我会给bobince的解决scheme,而不是。

如果url不以“/”开头

把当前页面的url去掉,去掉最后一个'/'; 然后追加相对的url。

否则,如果url以'/'开始

采取当前页面的url,砍掉单个“/”右侧的所有内容; 然后追加url。

否则,如果url开始与#或?

采取当前页面的url,并简单地追加url


希望对你有帮助

如果它在浏览器中运行,这种工作对我来说..

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