web-dev-qa-db-fra.com

Comment analyser une URL dans hostname et path en javascript?

Je voudrais prendre une ficelle

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

et le traiter dans un objet tel que

a.hostname == "example.com"

et

a.pathname == "/aa/bb"
324
freddiefujiwara
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"
349
freddiefujiwara

La manière moderne:

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

Retourne un objet avec les propriétés hostname et pathname, avec quelques autres .

Le premier argument est une URL relative ou absolue. s'il est relatif, vous devez spécifier le deuxième argument (l'URL de base). Par exemple, pour une URL relative à la page en cours:

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

Outre les navigateurs, cette API est également disponible dans Node.js depuis la v7, via require('url').URL.

302
rvighne

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"
278
Joseph Oster

Voici une fonction simple utilisant une expression rationnelle qui imite le comportement du tag a.

Avantages

  • comportement prévisible (pas de problèmes de navigateur)
  • n'a pas besoin du DOM
  • c'est vraiment court.

Les inconvénients

  • L'expression rationnelle 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"
}
*/

MODIFIER:

Voici une ventilation 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);
104
Rems

la réponse de freddiefujiwara est plutôt bonne, mais je devais également prendre en charge les URL relatives dans Internet Explorer. Je suis venu avec 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 JSFiddle: http://jsfiddle.net/6AEAB/

60
Claus
var loc = window.location;  // => "http://example.com:3000/pathname/?search=test#hash"

renvoie le currentUrl.

Si vous voulez passer votre propre chaîne sous forme d'URL ( ne fonctionne pas dans IE11 ):

var loc = new URL("http://example.com:3000/pathname/?search=test#hash")

Ensuite, vous pouvez l'analyser comme ceci:

loc.protocol; // => "http:"
loc.Host;     // => "example.com:3000"
loc.hostname; // => "example.com"
loc.port;     // => "3000"
loc.pathname; // => "/pathname/"
loc.hash;     // => "#hash"
loc.search;   // => "?search=test"
55
Peter Graham

js-uri (disponible sur Google Code) prend une URL de chaîne et résout un objet URI:

var some_uri = new URI("http://www.example.com/foo/bar");

alert(some_uri.authority); // www.example.com
alert(some_uri);           // http://www.example.com/foo/bar

var blah      = new URI("blah");
var blah_full = blah.resolve(some_uri);
alert(blah_full);         // http://www.example.com/foo/blah
17
Rex M

Qu'en est-il de la simple expression régulière?

url = "http://www.example.com/path/to/somwhere";
urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(url);
hostname = urlParts[1]; // www.example.com
path = urlParts[2]; // /path/to/somwhere
12
svestka

Voici une version que j'ai copiée à partir de https://Gist.github.com/1847816 , mais réécrite afin de faciliter la lecture et le débogage. Le but de la copie des données d'ancrage dans une autre variable nommée "résultat" est que les données d'ancrage sont assez longues. Par conséquent, la copie d'un nombre limité de valeurs dans le résultat contribuera à simplifier le résultat.

/**
 * See: https://Gist.github.com/1847816
 * Parse a URI, returning an object similar to Location
 * Usage: var uri = parseUri("hello?search#hash")
 */
function parseUri(url) {

  var result = {};

  var anchor = document.createElement('a');
  anchor.href = url;

  var keys = 'protocol hostname Host pathname port search hash href'.split(' ');
  for (var keyIndex in keys) {
    var currentKey = keys[keyIndex]; 
    result[currentKey] = anchor[currentKey];
  }

  result.toString = function() { return anchor.href; };
  result.requestUri = result.pathname + result.search;  
  return result;

}
8
Biagio Arobba

aujourd'hui, je rencontre ce problème et j'ai trouvé: RL - API Web MDN

var url = new URL("http://test.example.com/dir/subdir/file.html#hash");

Ce retour:

{ hash:"#hash", Host:"test.example.com", hostname:"test.example.com", href:"http://test.example.com/dir/subdir/file.html#hash", Origin:"http://test.example.com", password:"", pathname:"/dir/subdir/file.html", port:"", protocol:"http:", search: "", username: "" }

En espérant que ma première contribution vous aide!

7
A. Moynet

Analyse d'URL entre navigateurs , contourne le problème de chemin relatif pour IE 6, 7, 8 et 9:

function ParsedUrl(url) {
    var parser = document.createElement("a");
    parser.href = url;

    // IE 8 and 9 dont load the attributes "protocol" and "Host" in case the source URL
    // is just a pathname, that is, "/example" and not "http://domain.com/example".
    parser.href = parser.href;

    // IE 7 and 6 wont load "protocol" and "Host" even with the above workaround,
    // so we take the protocol/Host from window.location and place them manually
    if (parser.Host === "") {
        var newProtocolAndHost = window.location.protocol + "//" + window.location.Host;
        if (url.charAt(1) === "/") {
            parser.href = newProtocolAndHost + url;
        } else {
            // the regex gets everything up to the last "/"
            // /path/takesEverythingUpToAndIncludingTheLastForwardSlash/thisIsIgnored
            // "/" is inserted before because IE takes it of from pathname
            var currentFolder = ("/"+parser.pathname).match(/.*\//)[0];
            parser.href = newProtocolAndHost + currentFolder + url;
        }
    }

    // copies all the properties to this object
    var properties = ['Host', 'hostname', 'hash', 'href', 'port', 'protocol', 'search'];
    for (var i = 0, n = properties.length; i < n; i++) {
      this[properties[i]] = parser[properties[i]];
    }

    // pathname is special because IE takes the "/" of the starting of pathname
    this.pathname = (parser.pathname.charAt(0) !== "/" ? "/" : "") + parser.pathname;
}

Utilisation ( démo JSFiddle ici ):

var myUrl = new ParsedUrl("http://www.example.com:8080/path?query=123#fragment");

Résultat:

{
    hash: "#fragment"
    Host: "www.example.com:8080"
    hostname: "www.example.com"
    href: "http://www.example.com:8080/path?query=123#fragment"
    pathname: "/path"
    port: "8080"
    protocol: "http:"
    search: "?query=123"
}
5
acdcjunior

Pour ceux qui recherchent une solution moderne qui fonctionne dans IE, Firefox et Chrome:

Aucune de ces solutions qui utilisent un élément de lien hypertexte ne fonctionnera de la même manière en chrome. Si vous transmettez une URL non valide (ou vide) à chrome, elle renverra toujours l'hôte à partir duquel le script est appelé. Ainsi, dans IE, vous obtiendrez un blanc, alors que dans Chrome, vous obtiendrez localhost (ou autre chose).

Si vous essayez de regarder le référant, c'est trompeur. Vous voudrez vous assurer que l'hôte que vous avez récupéré était dans l'URL d'origine pour traiter ceci:

    function getHostNameFromUrl(url) {
        // <summary>Parses the domain/Host from a given url.</summary>
        var a = document.createElement("a");
        a.href = url;

        // Handle chrome which will default to domain where script is called from if invalid
        return url.indexOf(a.hostname) != -1 ? a.hostname : '';
    }
5
KingOfHypocrites

La manière AngularJS - violon ici: http://jsfiddle.net/PT5BG/4/

<!DOCTYPE html>
<html>
<head>
    <title>Parse URL using AngularJS</title>
</head>
<body ng-app ng-controller="AppCtrl" ng-init="init()">

<h3>Parse URL using AngularJS</h3>

url: <input type="text" ng-model="url" value="" style="width:780px;">

<ul>
    <li>href = {{parser.href}}</li>
    <li>protocol = {{parser.protocol}}</li>
    <li>Host = {{parser.Host}}</li>
    <li>hostname = {{parser.hostname}}</li>
    <li>port = {{parser.port}}</li>
    <li>pathname = {{parser.pathname}}</li>
    <li>hash = {{parser.hash}}</li>
    <li>search = {{parser.search}}</li>
</ul>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>

<script>
function AppCtrl($scope) {

    $scope.$watch('url', function() {
        $scope.parser.href = $scope.url;
    });

    $scope.init = function() {
        $scope.parser = document.createElement('a');
        $scope.url = window.location;
    }

}
</script>

</body>
</html>
4
Joseph Oster

Solution simple et robuste utilisant le modèle de module. Cela inclut un correctif pour IE où la pathname n'a pas toujours de barre oblique (/).

J'ai créé un Gist avec un JSFiddle qui propose un analyseur syntaxique plus dynamique. Je vous recommande de vérifier et de fournir des commentaires.

var URLParser = (function (document) {
    var PROPS = 'protocol hostname Host pathname port search hash href'.split(' ');
    var self = function (url) {
        this.aEl = document.createElement('a');
        this.parse(url);
    };
    self.prototype.parse = function (url) {
        this.aEl.href = url;
        if (this.aEl.Host == "") {
           this.aEl.href = this.aEl.href;
        }
        PROPS.forEach(function (prop) {
            switch (prop) {
                case 'hash':
                    this[prop] = this.aEl[prop].substr(1);
                    break;
                default:
                    this[prop] = this.aEl[prop];
            }
        }, this);
        if (this.pathname.indexOf('/') !== 0) {
            this.pathname = '/' + this.pathname;
        }
        this.requestUri = this.pathname + this.search;
    };
    self.prototype.toObj = function () {
        var obj = {};
        PROPS.forEach(function (prop) {
            obj[prop] = this[prop];
        }, this);
        obj.requestUri = this.requestUri;
        return obj;
    };
    self.prototype.toString = function () {
        return this.href;
    };
    return self;
})(document);

Démo

var URLParser = (function(document) {
  var PROPS = 'protocol hostname Host pathname port search hash href'.split(' ');
  var self = function(url) {
    this.aEl = document.createElement('a');
    this.parse(url);
  };
  self.prototype.parse = function(url) {
    this.aEl.href = url;
    if (this.aEl.Host == "") {
      this.aEl.href = this.aEl.href;
    }
    PROPS.forEach(function(prop) {
      switch (prop) {
        case 'hash':
          this[prop] = this.aEl[prop].substr(1);
          break;
        default:
          this[prop] = this.aEl[prop];
      }
    }, this);
    if (this.pathname.indexOf('/') !== 0) {
      this.pathname = '/' + this.pathname;
    }
    this.requestUri = this.pathname + this.search;
  };
  self.prototype.toObj = function() {
    var obj = {};
    PROPS.forEach(function(prop) {
      obj[prop] = this[prop];
    }, this);
    obj.requestUri = this.requestUri;
    return obj;
  };
  self.prototype.toString = function() {
    return this.href;
  };
  return self;
})(document);

/* Main */
var out = document.getElementById('out');
var urls = [
  'https://www.example.org:5887/foo/bar?a=1&b=2#section-1',
  'ftp://www.files.com:22/folder?id=7'
];
var parser = new URLParser();
urls.forEach(function(url) {
  parser.parse(url);
  println(out, JSON.stringify(parser.toObj(), undefined, ' '), 0, '#0000A7');
});

/* Utility functions */
function print(el, text, bgColor, fgColor) {
  var span = document.createElement('span');
  span.innerHTML = text;
  span.style['backgroundColor'] = bgColor || '#FFFFFF';
  span.style['color'] = fgColor || '#000000';
  el.appendChild(span);
}
function println(el, text, bgColor, fgColor) {
  print(el, text, bgColor, fgColor);
  el.appendChild(document.createElement('br'));
}
body {
  background: #444;
}
span {
  background-color: #fff;
  border: thin solid black;
  display: inline-block;
}
#out {
  display: block;
  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
  font-size: 12px;
  white-space: pre;
}
<div id="out"></div>

Sortie

{
 "protocol": "https:",
 "hostname": "www.example.org",
 "Host": "www.example.org:5887",
 "pathname": "/foo/bar",
 "port": "5887",
 "search": "?a=1&b=2",
 "hash": "section-1",
 "href": "https://www.example.org:5887/foo/bar?a=1&b=2#section-1",
 "requestUri": "/foo/bar?a=1&b=2"
}
{
 "protocol": "ftp:",
 "hostname": "www.files.com",
 "Host": "www.files.com:22",
 "pathname": "/folder",
 "port": "22",
 "search": "?id=7",
 "hash": "",
 "href": "ftp://www.files.com:22/folder?id=7",
 "requestUri": "/folder?id=7"
}
3
Mr. Polywhirl

Pourquoi ne pas l'utiliser?

        $scope.get_location=function(url_str){
        var parser = document.createElement('a');
        parser.href =url_str;//"http://example.com:3000/pathname/?search=test#hash";
        var info={
            protocol:parser.protocol,   
            hostname:parser.hostname, // => "example.com"
            port:parser.port,     // => "3000"
            pathname:parser.pathname, // => "/pathname/"
            search:parser.search,   // => "?search=test"
            hash:parser.hash,     // => "#hash"
            Host:parser.Host, // => "example.com:3000"      
        }
        return info;
    }
    alert( JSON.stringify( $scope.get_location("http://localhost:257/index.php/deploy/?asd=asd#asd"),null,4 ) );
3
tanthuc

Utilisez https://www.npmjs.com/package/uri-parse-lib pour cela

var t = parserURI("http://user:[email protected]:8080/directory/file.ext?query=1&next=4&sed=5#anchor");
3

Arrêtez de réinventer la roue. Utilisez https://github.com/medialize/URI.js/

var uri = new URI("http://example.org:80/foo/hello.html");
// get Host
uri.Host(); // returns string "example.org:80"
// set Host
uri.Host("example.org:80");
2
Hugo Sequeira

Vous pouvez également utiliser parse_url() fonction de Locutus projet (ancien php.js).

Code:

parse_url('http://username:password@hostname/path?arg=value#anchor');

Résultat:

{
  scheme: 'http',
  Host: 'hostname',
  user: 'username',
  pass: 'password',
  path: '/path',
  query: 'arg=value',
  fragment: 'anchor'
}
2
Andrey Rudenko
function parseUrl(url) {
    var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*):([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
        r = {
            hash: m[10] || "",                   // #asd
            Host: m[3] || "",                    // localhost:257
            hostname: m[6] || "",                // localhost
            href: m[0] || "",                    // http://username:password@localhost:257/deploy/?asd=asd#asd
            Origin: m[1] || "",                  // http://username:password@localhost:257
            pathname: m[8] || (m[1] ? "/" : ""), // /deploy/
            port: m[7] || "",                    // 257
            protocol: m[2] || "",                // http:
            search: m[9] || "",                  // ?asd=asd
            username: m[4] || "",                // username
            password: m[5] || ""                 // password
        };
    if (r.protocol.length == 2) {
        r.protocol = "file:///" + r.protocol.toUpperCase();
        r.Origin = r.protocol + "//" + r.Host;
    }
    r.href = r.Origin + r.pathname + r.search + r.hash;
    return m && r;
};
parseUrl("http://username:password@localhost:257/deploy/?asd=asd#asd");

Cela fonctionne avec les urls absolus et relatifs

2
Nikolay

Il suffit d’utiliser la bibliothèque url.js (pour Web et node.js).

https://github.com/websanova/js-url

url: http://example.com?param=test#param=again

url('?param'); // test
url('#param'); // again
url('protocol'); // http
url('port'); // 80
url('domain'); // example.com
url('tld'); // com

etc...
1
Rob