Convert relative path to absolute using JavaScript

后端 未结 11 1545
误落风尘
误落风尘 2020-11-28 05:15

There\'s a function, which gives me urls like:

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

It\'s always a relative path.

<
相关标签:
11条回答
  • 2020-11-28 05:18

    This should do it:

    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("/");
    }
    
    0 讨论(0)
  • 2020-11-28 05:18

    This will work. but only when you open a page with it's file name. it will not work well when you open a link like this stackoverflow.com/page. it will work with stackoverflow.com/page/index.php

    function reltoabs(link){
        let absLink = location.href.split("/");
        let relLink = link;
        let slashesNum = link.match(/[.]{2}\//g) ? link.match(/[.]{2}\//g).length : 0;
        for(let i = 0; i < slashesNum + 1; i++){
            relLink = relLink.replace("../", "");
            absLink.pop();
        }
        absLink = absLink.join("/");
        absLink += "/" + relLink;
        return absLink;
    }
    
    0 讨论(0)
  • 2020-11-28 05:20

    The most simple, efficient and correct way to do so it to just use 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", document.baseURI).href
    //=> "https://stackoverflow.com/questions/mypath"
    

    Performance wise, this solution is on par with using string manipulation and twice as fast as creating a tag.

    0 讨论(0)
  • 2020-11-28 05:20

    If you want to make a relative-to-absolute conversion for a link from a custom webpage in your browser (not for the page that runs your script), you can use a more enhanced version of the function suggested by @Bergi:

    var resolveURL=function resolve(url, base){
        if('string'!==typeof url || !url){
            return null; // wrong or empty url
        }
        else if(url.match(/^[a-z]+\:\/\//i)){ 
            return url; // url is absolute already 
        }
        else if(url.match(/^\/\//)){ 
            return 'http:'+url; // url is absolute already 
        }
        else if(url.match(/^[a-z]+\:/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('/');
    }
    

    It'll return null if something is wrong.

    Usage:

    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
    
    0 讨论(0)
  • 2020-11-28 05:24

    Javascript will do it for you. There's no need to create a 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"
    

    But if you need it as a function:

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

    Update: Simpler version if you need the full absolute path:

    var absolutePath = function(href) {
        var link = document.createElement("a");
        link.href = href;
        return link.href;
    }
    
    0 讨论(0)
  • 2020-11-28 05:25

    The href solution only works once the document is loaded (at least in IE11). This worked for me:

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

    See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

    0 讨论(0)
提交回复
热议问题