使用JavaScript将相对path转换为绝对path

有一个function,这给了我urls如:

./some.css ./extra/some.css ../../lib/slider/slider.css 

这总是一条相对path。

让我们认为我们知道页面的当前path,如http://site.com/stats/2012/ ,不知道如何将这些相对path转换为真正的path?

我们应该得到这样的东西:

 ./some.css => http://site.com/stats/2012/some.css ./extra/some.css => http://site.com/stats/2012/extra/some.css ../../lib/slider/slider.css => http://site.com/lib/slider/slider.css 

没有jQuery,只有香草的JavaScript。

这应该做到这一点:

 function absolute(base, relative) { var stack = base.split("/"), parts = relative.split("/"); stack.pop(); // remove current file name (or empty string) // (omit if "base" is the current folder without trailing slash) for (var i=0; i<parts.length; i++) { if (parts[i] == ".") continue; if (parts[i] == "..") stack.pop(); else stack.push(parts[i]); } return stack.join("/"); } 

Javascript会为你做。 不需要创build一个function。 不需要设置基准名称。

 var link = document.createElement("a"); link.href = "../../lib/slider/slider.css"; alert(link.protocol+"//"+link.host+link.pathname+link.search+link.hash); //output will be "http://www.yoursite.com/lib/slider/slider.css" 

如果你需要一个函数,只需要用三行代码把它作为一个函数来包装。

 var absolutePath = function(href) { var link = document.createElement("a"); link.href = href; return (link.protocol+"//"+link.host+link.pathname+link.search+link.hash); } 

最简单,最有效,最正确的方法就是使用URL api。

 new URL("http://www.stackoverflow.com?q=hello").href; //http://www.stackoverflow.com/?q=hello" new URL("mypath","http://www.stackoverflow.com").href; //"http://www.stackoverflow.com/mypath" new URL("../mypath","http://www.stackoverflow.com/search").href //"http://www.stackoverflow.com/mypath" new URL("../mypath", window.location.href).href //"https://stackoverflow.com/questions/mypath" 

请参阅JSPerf 。 这个解决scheme与使用string操作一样,比创build标签快两倍。

这来自MDN是牢不可破的!

 /*\ |*| |*| :: translate relative paths to absolute paths :: |*| |*| https://developer.mozilla.org/en-US/docs/Web/API/document.cookie |*| |*| The following code is released under the GNU Public License, version 3 or later. |*| http://www.gnu.org/licenses/gpl-3.0-standalone.html |*| \*/ function relPathToAbs (sRelPath) { var nUpLn, sDir = "", sPath = location.pathname.replace(/[^\/]*$/, sRelPath.replace(/(\/|^)(?:\.?\/+)+/g, "$1")); for (var nEnd, nStart = 0; nEnd = sPath.indexOf("/../", nStart), nEnd > -1; nStart = nEnd + nUpLn) { nUpLn = /^\/(?:\.\.\/)*/.exec(sPath.slice(nEnd))[0].length; sDir = (sDir + sPath.substring(nStart, nEnd)).replace(new RegExp("(?:\\\/+[^\\\/]*){0," + ((nUpLn - 1) / 3) + "}$"), "/"); } return sDir + sPath.substr(nStart); } 

示例用法:

 /* Let us be in /en-US/docs/Web/API/document.cookie */ alert(location.pathname); // displays: /en-US/docs/Web/API/document.cookie alert(relPathToAbs("./")); // displays: /en-US/docs/Web/API/ alert(relPathToAbs("../Guide/API/DOM/Storage")); // displays: /en-US/docs/Web/Guide/API/DOM/Storage alert(relPathToAbs("../../Firefox")); // displays: /en-US/docs/Firefox alert(relPathToAbs("../Guide/././API/../../../Firefox")); // displays: /en-US/docs/Firefox 

如果您希望对浏览器中的自定义网页(不是运行脚本的页面)的链接进行相对至绝对的转换,则可以使用@Bergibuild议的function的更多增强版本:

 var resolveURL=function resolve(url, base){ if('string'!==typeof url || !url){ return null; // wrong or empty url } else if(url.match(/^[az]+\:\/\//i)){ return url; // url is absolute already } else if(url.match(/^\/\//)){ return 'http:'+url; // url is absolute already } else if(url.match(/^[az]+\:/i)){ return url; // data URI, mailto:, tel:, etc. } else if('string'!==typeof base){ var a=document.createElement('a'); a.href=url; // try to resolve url without base if(!a.pathname){ return null; // url not valid } return 'http://'+url; } else{ base=resolve(base); // check base if(base===null){ return null; // wrong base } } var a=document.createElement('a'); a.href=base; if(url[0]==='/'){ base=[]; // rooted path } else{ base=a.pathname.split('/'); // relative path base.pop(); } url=url.split('/'); for(var i=0; i<url.length; ++i){ if(url[i]==='.'){ // current directory continue; } if(url[i]==='..'){ // parent directory if('undefined'===typeof base.pop() || base.length===0){ return null; // wrong url accessing non-existing parent directories } } else{ // child directory base.push(url[i]); } } return a.protocol+'//'+a.hostname+base.join('/'); } 

如果出现错误,它将返回null

用法:

 resolveURL('./some.css', 'http://example.com/stats/2012/'); // returns http://example.com/stats/2012/some.css resolveURL('extra/some.css', 'http://example.com/stats/2012/'); // returns http://example.com/stats/2012/extra/some.css resolveURL('../../lib/slider/slider.css', 'http://example.com/stats/2012/'); // returns http://example.com/lib/slider/slider.css resolveURL('/rootFolder/some.css', 'https://example.com/stats/2012/'); // returns https://example.com/rootFolder/some.css resolveURL('localhost'); // returns http://localhost resolveURL('../non_existing_file', 'example.com') // returns null 
 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; } 

这也适用于IE6,不像其他一些解决scheme(请参阅从相对path获取绝对URL)(IE6问题) )

href解决scheme只有在文档加载后才起作用(至less在IE11中)。 这对我工作:

 link = link || document.createElement("a"); link.href = window.location.href + "/../" + href; return link.href; 

build议并接受的解决scheme不支持服务器相对的URL,不适用于绝对URL。 如果我的亲戚是/网站/ folder1它不会工作,例如。

这是另一个function,支持完整的,服务器相对或相对的URL以及../为一个层次。 这并不完美,但涵盖了很多select。 当您的基本url不是当前页面的url时使用这个,否则有更好的select。

  function relativeToAbsolute(base, relative) { //make sure base ends with / if (base[base.length - 1] != '/') base += '/'; //base: https://server/relative/subfolder/ //url: https://server let url = base.substr(0, base.indexOf('/', base.indexOf('//') + 2)); //baseServerRelative: /relative/subfolder/ let baseServerRelative = base.substr(base.indexOf('/', base.indexOf('//') + 2)); if (relative.indexOf('/') === 0)//relative is server relative url += relative; else if (relative.indexOf("://") > 0)//relative is a full url, ignore base. url = relative; else { while (relative.indexOf('../') === 0) { //remove ../ from relative relative = relative.substring(3); //remove one part from baseServerRelative. /relative/subfolder/ -> /relative/ if (baseServerRelative !== '/') { let lastPartIndex = baseServerRelative.lastIndexOf('/', baseServerRelative.length - 2); baseServerRelative = baseServerRelative.substring(0, lastPartIndex + 1); } } url += baseServerRelative + relative;//relative is a relative to base. } return url; } 

希望这可以帮助。 在JavaScript中没有这个基本的工具是非常令人沮丧的。

我必须为接受的解决scheme添加一个修复程序,因为在我们的angularjs导航中#之后可以有斜线。

 function getAbsoluteUrl(base, relative) { // remove everything after # var hashPosition = base.indexOf('#'); if (hashPosition > 0){ base = base.slice(0, hashPosition); } // the rest of the function is taken from http://stackoverflow.com/a/14780463 // http://stackoverflow.com/a/25833886 - this doesn't work in cordova // http://stackoverflow.com/a/14781678 - this doesn't work in cordova var stack = base.split("/"), parts = relative.split("/"); stack.pop(); // remove current file name (or empty string) // (omit if "base" is the current folder without trailing slash) for (var i=0; i<parts.length; i++) { if (parts[i] == ".") continue; if (parts[i] == "..") stack.pop(); else stack.push(parts[i]); } return stack.join("/"); }