我想拿一根绳子
var a = "http://example.com/aa/bb/"
然后把它加工成一个物体
a.hostname == "example.com"
and
a.pathname == "/aa/bb"
我想拿一根绳子
var a = "http://example.com/aa/bb/"
然后把它加工成一个物体
a.hostname == "example.com"
and
a.pathname == "/aa/bb"
当前回答
使用模块模式的简单而健壮的解决方案。这包括修复IE的路径名不总是有前导正斜杠(/)。
我已经创建了一个Gist和一个JSFiddle,它提供了一个更动态的解析器。我建议你检查一下并提供反馈。
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);
Demo
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>
输出
{
"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"
}
其他回答
这不会解析查询和散列,但除此之外它工作得很好。
const getURIParts = (url) => { const matches = url.match(/^(\w+?:\/\/)?([\w-\.]+(?=\/?))?:?(\d*)?([^:]*)/) return { scheme: matches ? matches[1] : undefined, host: matches ? matches[2] : '', port: matches ? matches[3] : undefined, pathname: matches ? matches[4] : '' } } console.log(getURIParts("")) console.log(getURIParts("http://localhost/bla")) console.log(getURIParts("https://api.spotify.com/")) console.log(getURIParts("https://api.spotify.com")) console.log(getURIParts("wss://wss.slack.com/link/?ticket=1234-5678")) console.log(getURIParts("localhost")) console.log(getURIParts("localhost/bla")) console.log(getURIParts("localhost/")) console.log(getURIParts("api.spotify.com/bla/two")) console.log(getURIParts("api.spotify.com:8000/bla/two")) console.log(getURIParts("https://api.spotify.com:8800/")) console.log(getURIParts("/mp3-preview/f504e6b8e037771318656394f532dede4f9bcaea"))
freddiefujiwara的答案很好,但我也需要在ie中支持相对url。我想出了以下解决方案:
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 a = getLocation('http://example.com/aa/bb/');
document.write(a.hostname);
document.write(a.pathname);
例子:
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);
当然,在>2016年,正确的答案是使用URL API 对于页面URL window.location And for <a href="…""> html lanchorelement API
也支持旧浏览器,使用polyfill:
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=URL"></script>
但作为另一种选择,它可以通过RegEx模式简单而准确地处理:
function URIinfo(s) { s=s.match(/^(([^/]*?:)\/*((?:([^:]+):([^@]+)@)?([^/:]{2,}|\[[\w:]+])(:\d*)?(?=\/|$))?)?((.*?\/)?(([^/]*?)(\.[^/.]+?)?))(\?.*?)?(#.*)?$/); return {origin:s[1],protocol:s[2],host:s[3],username:s[4],password:s[5],hostname:s[6],port:s[7],path:s[8],folders:s[9],file:s[10],filename:s[11],fileext:s[12],search:s[13],hash:s[14]}; } var sample='http://user:password@my.site.com:8080/onefolder/folder.name/file.min.js?query=http://my.site.com:8080/file.exe#hash-root:/file/1.txt'; console.log (URIinfo(sample)); /* { "origin": "http://user:password@my.site.com:8080", "protocol": "http:", "host": "user:password@my.site.com:8080", "username": "user", "password": "password", "hostname": "my.site.com", "port": ":8080", "path": "/onefolder/folder.name/file.min.js", "folders": "/onefolder/folder.name/", "file": "file.min.js", "filename": "file.min", "fileext": ".js", "search": "?query=http://my.site.com:8080/file.exe", "hash": "#hash-root:/file/1.txt" } */
使用正则表达式
任何形式的
绝对/相对路径 IPv4 / IPv6 网络协议/本地文件 查询/散列
返回所有URL选项,但不返回searchParams
(+)也将返回文件信息,如PHP pathInfo
在这里找到: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"
别再白费力气了。使用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");