95 votes

Convertir un chemin relatif en chemin absolu en utilisant JavaScript

Il y a une fonction, qui me donne des urls comme :

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

C'est toujours un chemin relatif.

Imaginons que nous connaissions le chemin d'accès actuel de la page, par exemple http://site.com/stats/2012/ Je ne sais pas comment convertir ces chemins relatifs en chemins réels.

Nous devrions obtenir quelque chose comme :

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

Pas de jQuery, uniquement du javascript classique.

3voto

Sebastien Lorber Points 9682
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;
}

Cela fonctionne aussi sur IE6, contrairement à d'autres solutions (voir Obtenir une URL absolue à partir d'une URL relative. (problème IE6) )

3voto

illogicalapple Points 21

Je sais que c'est une très vieille question, mais vous pourriez le faire avec : (new URL(relativePath, location)).href .

2voto

Shai Petel Points 71

La solution proposée et acceptée ne prend pas en charge les URL relatives au serveur et ne fonctionne pas sur les URL absolues. Si mon URL relative est /sites/folder1, cela ne fonctionnera pas, par exemple.

Voici une autre fonction qui prend en charge les URL complètes, relatives au serveur ou relatives ainsi que ../ pour un niveau supérieur. Elle n'est pas parfaite mais couvre un grand nombre d'options. Utilisez-la lorsque votre URL de base n'est pas l'URL de la page en cours, sinon il existe de meilleures alternatives.

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

J'espère que cela vous aidera. Il était vraiment frustrant de ne pas disposer de cet utilitaire de base en JavaScript.

1voto

Corey Alix Points 365

La solution des href ne fonctionne qu'une fois le document chargé (du moins dans IE11). Ceci a fonctionné pour moi :

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

Véase https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

0voto

Stanislav Points 911

J'ai dû ajouter un correctif à la solution acceptée parce que nous pouvons avoir des slashs après # dans notre navigation 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("/");
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X