432 votes

Comment analyser une URL en nom d'hôte et en chemin d'accès en javascript ?

Je voudrais prendre une corde

var a = "http://example.com/aa/bb/"

et le transformer en un objet tel que

a.hostname == "example.com"

y

a.pathname == "/aa/bb"

11 votes

Dans le cas où vous travaillez sur l'URL actuel, vous pouvez accéder à hostname y pathname directement à partir du location objet.

1 votes

Qu'en est-il de "lastPathPart" ?

0 votes

Pas de regex mais le module Python tldextract fait exactement cela : github.com/john-kurkowski/tldextract

491voto

rvighne Points 2382

La méthode moderne :

new URL("http://example.com/aa/bb/")

Retourne un objet avec des propriétés hostname y pathname ainsi que quelques autres .

Le premier argument est une URL relative ou absolue ; si elle est relative, vous devez spécifier le deuxième argument (l'URL de base). Par exemple, pour une URL relative à la page actuelle :

new URL("/aa/bb/", location)

En plus des navigateurs, cette API est également disponible en Node.js depuis la v7, par require('url').URL .

11 votes

Super ! Les URLs relatives ne fonctionnent pas... :( new URL('/stuff?foo=bar#baz') -> SyntaxError: Failed to construct 'URL': Invalid URL

3 votes

@lakenen : J'ai ajouté un correctif à ma réponse.

1 votes

Le seul problème est qu'il faut maintenant analyser soi-même si c'est relatif ou absolu. IMO, cela devrait simplement être géré par URL . Peut-être pouvons-nous l'intégrer dans les spécifications ? :P

374voto

freddiefujiwara Points 7522
var getLocation = function(href) {
    var l = document.createElement("a");
    l.href = href;
    return l;
};
var l = getLocation("http://example.com/path");
console.debug(l.hostname)
>> "example.com"
console.debug(l.pathname)
>> "/path"

15 votes

Êtes-vous sûr que cette solution est compatible avec tous les navigateurs ?

0 votes

Href est un type d'attribut DOM spécial avec ces propriétés supplémentaires de type URI. Très intéressant !

75 votes

Il convient de noter que, même si cela peut aider/répondre à l'affiche originale, cette réponse ne fonctionnera que pour les personnes effectuant des travaux de JS dans un navigateur, car elle s'appuie sur le DOM pour effectuer son travail.

313voto

Joseph Oster Points 1089

Trouvé ici : https://gist.github.com/jlong/2428561

var parser = document.createElement('a');
parser.href = "http://example.com:3000/pathname/?search=test#hash";

parser.protocol; // => "http:"
parser.host;     // => "example.com:3000"
parser.hostname; // => "example.com"
parser.port;     // => "3000"
parser.pathname; // => "/pathname/"
parser.hash;     // => "#hash"
parser.search;   // => "?search=test"
parser.origin;   // => "http://example.com:3000"

11 votes

Notez que si vous voulez seulement obtenir les parties analysées de l'emplacement actuel du navigateur, les deux premières lignes deviennent parser = location; et toutes les lignes suivantes fonctionnent. Je viens de l'essayer dans Chrome et IE9.

9 votes

Notez également que pathname n'inclut pas le slash de tête dans IE. Allez comprendre :D

3 votes

Pour IE, utilisez "/" + parser.pathname

124voto

Rems Points 170

Voici une fonction simple utilisant une regexp qui imite la fonction a le comportement des balises.

Pour

  • comportement prévisible (pas de problèmes liés aux différents navigateurs)
  • n'a pas besoin du DOM
  • c'est vraiment court.

Cons

  • Le regexp est un peu difficile à lire.

-

function getLocation(href) {
    var match = href.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
    return match && {
        href: href,
        protocol: match[1],
        host: match[2],
        hostname: match[3],
        port: match[4],
        pathname: match[5],
        search: match[6],
        hash: match[7]
    }
}

-

getLocation("http://example.com/");
/*
{
    "protocol": "http:",
    "host": "example.com",
    "hostname": "example.com",
    "port": undefined,
    "pathname": "/"
    "search": "",
    "hash": "",
}
*/

getLocation("http://example.com:3000/pathname/?search=test#hash");
/*
{
    "protocol": "http:",
    "host": "example.com:3000",
    "hostname": "example.com",
    "port": "3000",
    "pathname": "/pathname/",
    "search": "?search=test",
    "hash": "#hash"
}
*/

EDITAR:

Voici une décomposition de l'expression régulière

var reURLInformation = new RegExp([
    '^(https?:)//', // protocol
    '(([^:/?#]*)(?::([0-9]+))?)', // host (hostname and port)
    '(/{0,1}[^?#]*)', // pathname
    '(\\?[^#]*|)', // search
    '(#.*|)$' // hash
].join(''));
var match = href.match(reURLInformation);

4 votes

Ne fonctionne pas avec les URLs relatives. Avez-vous suivi la RFC-3986 lors de la création de la regexp ? > getLocation("//exemple.com/") ; null > getLocation("/pathname/?search") ; null > getLocation("/pathname/") ; null > getLocation("relative") ; null

2 votes

J'aime le fait que cela n'utilise pas le DOM, mais Gregers a un bon point. Ce serait bien si cela pouvait gérer les chemins relatifs. Cela nécessiterait d'utiliser window.location (un élément a) pour remplir les blancs et ajouter du code. Dans ce cas, la méthode deviendrait hypocrite. À moins qu'il n'y ait une alternative, je ne suis pas sûr que cela puisse être résolu parfaitement.

0 votes

Ajout de la clé href avec l'url d'origine, ce qui assure la cohérence de cet objet de retour avec l'implémentation dom.

66voto

Claus Points 264

La réponse de freddiefujiwara est assez bonne mais j'avais également besoin de prendre en charge les URL relatives dans Internet Explorer. J'ai trouvé la solution suivante :

function getLocation(href) {
    var location = document.createElement("a");
    location.href = href;
    // IE doesn't populate all link properties when setting .href with a relative URL,
    // however .href will return an absolute URL which then can be used on itself
    // to populate these additional fields.
    if (location.host == "") {
      location.href = location.href;
    }
    return location;
};

Maintenant, utilisez-le pour obtenir les propriétés nécessaires :

var a = getLocation('http://example.com/aa/bb/');
document.write(a.hostname);
document.write(a.pathname);

Exemple :

function getLocation(href) {
  var location = document.createElement("a");
  location.href = href;
  // IE doesn't populate all link properties when setting .href with a relative URL,
  // however .href will return an absolute URL which then can be used on itself
  // to populate these additional fields.
  if (location.host == "") {
    location.href = location.href;
  }
  return location;
};
var urlToParse = 'http://example.com/aa/bb/',
  a = getLocation(urlToParse);
document.write('Absolute URL: ' + urlToParse);
document.write('<br />');
document.write('Hostname: ' + a.hostname);
document.write('<br />');
document.write('Pathname: ' + a.pathname);

4 votes

Cela devrait être la réponse acceptée. Utilisation très intelligente de la gestion des URL relatives à absolues. +1

0 votes

Apparemment, ce n'est pas la première fois qu'un lien JSFiddle est mort : stackoverflow.com/questions/25179964/

3 votes

Cela a bien fonctionné, mais j'ai fait une mise à jour qui, je l'espère, aidera les autres. Je l'utilise pour vérifier l'origine d'une requête postMessage et lorsque le port est un port par défaut (80 ou 443), il n'est pas ajouté au chemin. Je l'ai vérifié de manière conditionnelle lors de la création de mon URL : var locationHost = (location.port !== '80' && location.port !== '443') ? location.host : location.hostname; var locationOrigin = location.protocol + '//' + locationHost;

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