Je voudrais prendre une ficelle
var a = "http://example.com/aa/bb/"
et le transformer en un objet tel que
a.hostname == "example.com"
et
a.pathname == "/aa/bb"
Je voudrais prendre une ficelle
var a = "http://example.com/aa/bb/"
et le transformer en un objet tel que
a.hostname == "example.com"
et
a.pathname == "/aa/bb"
Réponses:
La manière moderne:
new URL("http://example.com/aa/bb/")
Renvoie un objet avec des 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 actuelle:
new URL("/aa/bb/", location)
En plus des navigateurs, cette API est également disponible dans Node.js depuis la v7, à travers require('url').URL
.
new URL('/stuff?foo=bar#baz')
->SyntaxError: Failed to construct 'URL': Invalid URL
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"
pathname
supprime la barre oblique principale, contrairement aux autres navigateurs. Vous vous retrouverez donc avec /path
ou path
, selon votre navigateur.
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"
parser = location;
et toutes les lignes suivantes fonctionnent. Je l'ai essayé dans Chrome et IE9 tout à l'heure.
pathname
n'inclut pas la barre oblique principale dans IE. Allez comprendre. : D
http:
même si vous passez juste domain.com
en href (sans aucun protocole). Je voulais l'utiliser pour vérifier si le protocole manquait, et si c'est le cas, je pourrais l'ajouter, mais il suppose que http: n'a donc pas pu l'utiliser à cette fin.
Voici une fonction simple utilisant une expression rationnelle qui imite le a
comportement des balises.
Avantages
Les inconvénients
-
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"
}
*/
ÉDITER:
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);
var loc = window.location; // => "http://example.com:3000/pathname/?search=test#hash"
renvoie le currentUrl.
Si vous souhaitez 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:
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"
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 JSFiddle: http://jsfiddle.net/6AEAB/
var locationHost = (location.port !== '80' && location.port !== '443') ? location.host : location.hostname;
var locationOrigin = location.protocol + '//' + locationHost;
js-uri (disponible sur Google Code) prend une URL de chaîne et en 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
Qu'en est-il de l'expression régulière simple?
url = "http://www.example.com/path/to/somwhere";
urlParts = /^(?:\w+\:\/\/)?([^\/]+)(.*)$/.exec(url);
hostname = urlParts[1]; // www.example.com
path = urlParts[2]; // /path/to/somwhere
//user:password@example.com/path/x?y=z
et vous verrez pourquoi la simple expression régulière ne le coupe pas. Maintenant, jetez quelque chose d'invalide et il devrait également être renfloué de manière prévisible.
aujourd'hui je rencontre ce problème et j'ai trouvé: URL - MDN Web APIs
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!
Voici une version que j'ai copiée à partir de https://gist.github.com/1847816 , mais réécrite afin qu'elle soit plus facile à lire et à déboguer. Le but de la copie des données d'ancrage dans une autre variable nommée "résultat" est parce que les données d'ancrage sont assez longues, et donc la copie d'un nombre limité de valeurs dans le résultat aidera à 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;
}
Analyse d'URL inter-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"
}
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 dans Chrome. Si vous transmettez une URL non valide (ou vide) à Chrome, elle renverra toujours l'hôte d'où le script est appelé. Donc, dans IE, vous obtiendrez vide, tandis que dans Chrome, vous obtiendrez localhost (ou autre).
Si vous essayez de regarder le référent, c'est trompeur. Vous voudrez vous assurer que l'hôte que vous récupérez était dans l'URL d'origine pour gérer cela:
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 : '';
}
The AngularJS way - fiddle here: 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>
$document
et $window
services
Solution simple et robuste utilisant le modèle de module. Cela inclut un correctif pour IE où le pathname
n'a pas toujours une barre oblique ( /
).
J'ai créé un Gist avec un JSFiddle qui offre un analyseur plus dynamique. Je vous recommande de le 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);
{
"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"
}
Utilisez https://www.npmjs.com/package/uri-parse-lib pour cela
var t = parserURI("http://user:pass@example.com:8080/directory/file.ext?query=1&next=4&sed=5#anchor");
Pourquoi ne l'utilisez pas?
$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 ) );
Vous pouvez également utiliser la parse_url()
fonction du projet Locutus (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'
}
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");
Il fonctionne avec des URL absolues et relatives
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
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");
Utilisez simplement la bibliothèque url.js (pour le 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...
un simple hack avec la première réponse
var getLocation = function(href=window.location.href) {
var l = document.createElement("a");
l.href = href;
return l;
};
ceci peut être utilisé même sans argument pour déterminer le nom d'hôte actuel getLocation (). hostname donnera le nom d'hôte actuel
hostname
etpathname
directement à partir de l'location
objet.