var uri = new URI(); // same as new URI(location.href)
// string
var uri = new URI("http://example.org");
// URI object for cloning
var uri = new URI(new URI("http://example.org"));
// URI parts object
var uri = new URI({
protocol: 'http',
host: 'example.org'
});
// without new keyword
var uri = URI("http://example.org");
// resolving right in the constructor
var uri = URI("../foobar.html", "http://example.org/hello/world.html");
// which is exactly the same as
URI("../foobar.html").absoluteTo("http://example.org/hello/world.html");
// but specified in URL constructor
The following parts can be specified in an object:
var uri = new URI({
protocol: 'http', // no trailing :
username: 'user',
password: 'pass',
hostname: 'example.org',
port: '80', // string, please
// "path", not "pathname", sorry
path: '/foo/bar.html',
// "query", not "search", sorry
query: 'foo=bar&bar=baz', // no leading ?
// "fragment", not "hash", sorry
fragment: 'frag' // no leading #
});
using only components of URIs:
// Look ma! I'm only working the pathname
var uri = new URI("some/directory/file.html");
// Look ma! I'm only working the query string
var uri = new URI("?foo=bar");
// Look ma! I'm only working the fragment / hash
var uri = new URI("#call-me-hash");
// and any combination of the above…
var uri = new URI("http://example.org/foo/hello.html");
// get protocol
uri.protocol(); // returns string "http"
// set protocol
uri.protocol("ftp"); // returns the URI instance for chaining
var uri = new URI("http://user:[email protected]/foo/hello.html");
// get username
uri.username(); // returns string "user"
// set username
uri.username("user"); // returns the URI instance for chaining
var uri = new URI("http://user:[email protected]/foo/hello.html");
// get password
uri.password(); // returns string "pass"
// set password
uri.password("user"); // returns the URI instance for chaining
var uri = new URI("http://example.org/foo/hello.html");
// get protocol
uri.hostname(); // returns string
// set protocol
uri.hostname("example.org"); // returns the URI instance for chaining
NOTE: .hostname() returns the actual hostname, whereas .host() returns the hostname including the port
var uri = new URI("http://example.org:8080/foo/hello.html");
// get port
uri.port(); // returns string "8080"
// set port
uri.port("80"); // returns the URI instance for chaining
NOTE: although the port may be considered an integer, within URI it is a string.
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"); // returns the URI instance for chaining
NOTE: .hostname() returns the actual hostname, whereas .host() returns the hostname including the port
Authority is comprised of username, password, hostname and port
var uri = new URI("http://user:[email protected]:88/foo/hello.html");
// get authority
uri.authority(); // returns string "user:[email protected]:88"
// set authority
uri.authority("user:[email protected]:80"); // returns the URI instance for chaining
NOTE: .authority() will reset any of username, password and port if they're not specified.
.domain() is a convenience method that returns example.org from the hostname www.example.org.
var uri = new URI("http://example.org/foo/hello.html");
// get domain
uri.domain(); // returns string "example.org"
// set domain
uri.domain("otherdomain.com"); // returns the URI instance for chaining
NOTE: .domain() will throw an error if you pass it an empty string.
.subdomain() is a convenience method that returns www from the hostname www.example.org.
var uri = new URI("http://www.example.org/foo/hello.html");
// get subdomain
uri.subdomain(); // returns string "www"
// set subdomain
uri.subdomain("other.subdomain"); // returns the URI instance for chaining
.tld() is a convenience method that returns org from the hostname www.example.org.
var uri = new URI("http://example.org/foo/hello.html");
// get tld
uri.tld(); // returns string "org"
// set tld
uri.tld("com"); // returns the URI instance for chaining
NOTE: .tld() will throw an error if you pass it an empty string or use it on an IP-host.
.path() is an alias of .pathname()
var uri = new URI("http://example.org/foo/hello.html");
// get pathname
uri.pathname(); // returns string "/foo/hello.html"
// set pathname
uri.pathname("/foo/hello.html"); // returns the URI instance for chaining
// will encode for you
uri.pathname('/hello world/');
uri.pathname() === '/hello%20world/';
// will decode for you
uri.pathname(true) === '/hello world/';
.directory() is an convenience method for mutating the directory part of a path
var uri = new URI("http://example.org/foo/hello.html");
// get directory
uri.directory(); // returns string "/foo" (no trailing slash)
// set directory
uri.directory("/bar"); // returns the URI instance for chaining
// uri == "http://example.org/bar/hello.html"
// will encode for you
uri.directory('/hello world/');
uri.directory() === '/hello%20world';
// will decode for you
uri.directory(true) === '/hello world';
.filename() is an convenience method for mutating the filename part of a path
var uri = new URI("http://example.org/foo/hello.html");
// get filename
uri.filename(); // returns string "hello.html" (no leading slash)
// set filename
uri.filename("world.xml"); // returns the URI instance for chaining
// uri == "http://example.org/bar/world.xml"
// will encode for you
uri.filename('hello world.html');
uri.filename() === 'hello%20world.html';
// will decode for you
uri.filename(true) === 'hello world.html';
.suffix() is an convenience method for mutating the filename part of a path
var uri = new URI("http://example.org/foo/hello.html");
// get suffix
uri.suffix(); // returns string "html" (no leading dot)
// set suffix
uri.suffix("xml"); // returns the URI instance for chaining
// uri == "http://example.org/bar/world.xml"
// will encode for you
uri.suffix('würgh');
uri.suffix() === 'w%C3%BCrgh';
// will decode for you
uri.suffix(true) === 'würgh';
var uri = new URI("http://example.org/foo/hello.html?foo=bar&bar=baz");
// get search
uri.search(); // returns string "?foo=bar&bar=baz" (leading ?)
// get query
uri.query(); // returns string "foo=bar&bar=baz" (no leading ?)
// .query() and .search() behave the same for the following:
// set search
uri.search("?foo=bar&bar=baz"); // returns the URI instance for chaining
uri.search("foo=bar&bar=baz"); // returns the URI instance for chaining
// uri == "http://example.org/bar/world.html?foo=bar&bar=baz"
uri.search(""); // returns the URI instance for chaining
// uri == "http://example.org/bar/world.html"
// get data map:
uri.search(true); // returns { foo: "bar", hello : ["world", "mars"] }
// set data map:
uri.search({ foo: "bar", hello : ["world", "mars"] });
// uri == "http://example.org/bar/world.html?foo=bar&hello=world&hello=mars"
// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.search("?foo=bar&bar=baz");
uri.search("?foo=bar[]&bar[]=baz");
Note that names and values passed in an object are encoded automatically. The object, resulting from parsing the query string, contains decoded values
Hint: If you're using jQuery, have a look at their .serialize() function.
var uri = new URI("http://example.org/foo/hello.html#world");
// get hash
uri.hash(); // returns string "#world" (leading #)
// get fragment
uri.fragment(); // returns string "world" (no leading #)
// .hash() and .fragment() behave the same for the following:
// set hash
uri.hash("#mars"); // returns the URI instance for chaining
uri.hash("mars"); // returns the URI instance for chaining
// uri == "http://example.org/bar/world.xml#mars"
.is() tells what a URL is. It responds with a boolean and can be asked the following questions:
relativetrue if URL doesn't have a hostnamedomain, nametrue if hostname is not an IPidntrue if hostname contains non-alphanumeric characters and is not an IPpunycodetrue if hostname contains xn--iptrue if hostname is IPv4 or IPv6ip4, ipv4, inet4true if hostname is IPv4ip6, ipv6, inet6true if hostname is IPv6var uri = new URI("http://example.org/");
uri.is('relative') === false;
uri.is('name') === true;
uri.is('punycode') === false;
uri.is('IDN') === false; // case doesn't matter
uri.is('idn') === false; // case doesn't matter
uri.is('ip') === false;
var uri = new URI("http://123.123.123.123/");
uri.is('relative') === false;
uri.is('name') === false;
uri.is('IP') === true;
uri.is('IPv4') === true;
uri.is('IPv6') === false;
var uri = new URI("http://fe80:0000:0000:0000:0204:61ff:fe9d:f156/");
uri.is('IP') === true;
uri.is('IPv4') === false;
uri.is('IPv6') === true;
var uri = new URI("/hello/world.html");
uri.is('relative') === true;
uri.is('name') === false;
uri.is('IP') === false;
.addQuery() is an alias of .addSearch()
var uri = new URI("?hello=world");
uri.addSearch("hello", "mars"); // returns the URI instance for chaining
// uri == "?hello=world&hello=mars"
uri.addSearch({ foo: "bar", goodbye : ["world", "mars"] });
// uri == "?hello=world&hello=mars&foo=bar&goodbye=world&goodbye=mars"
// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.addSearch("foo", ["bar", "baz"]);
uri.addSearch("foo[]", ["bar", "baz"]);
Note that names and values passed in are encoded automatically.
.removeQuery() is an alias of .removeSearch()
var uri = new URI("?hello=world&hello=mars&foo=bar");
// remove an attribute
uri.removeSearch("hello"); // returns the URI instance for chaining
// uri == "?foo=bar"
// remove an attribute with value filter
uri.search("?hello=world&hello=mars&foo=bar");
uri.removeSearch("hello", "world"); // returns the URI instance for chaining
// uri == "?hello=mars&foo=bar"
// remove multiple values
uri.search("?hello=world&hello=mars&foo=bar&mine=true");
uri.removeSearch(["hello", "foo"]);
// uri == "?mine=true"
// remove multiple values with value filter
uri.search("?hello=world&hello=mars&foo=bar&mine=true&a=1&a=2&a=3");
uri.removeSearch({hello: "world", foo: undefined, a: ["1", "3"]});
// uri == "?hello=mars&mine=true&a=2"
executes normalizeProtocol(), normalizeHostname(), normalizePort(), normalizePath(), normalizeSearch(), normalizeHash()
var uri = new URI("hTTp://www.example.org/");
// normalize protocol
uri.normalizeProtocol(); // returns the URI instance for chaining
// uri == "http://www.example.org/"
For IDN conversion punycode.js must be available (bundled in URI.js). For IPv6-best-notation conversion IPv6.js must be available (bundled in URI.js). Also lower-cases hostnames.
var uri = new URI("http://www.exämple.org/");
// normalize IDN host
uri.normalizeHostname(); // returns the URI instance for chaining
// uri == "http://www.xn--exmple-cua.org/"
// normalize IPv6 host
uri.hostname('fe80:0000:0000:0000:0204:61ff:fe9d:f156');
uri.normalizeHostname(); // returns the URI instance for chaining
// uri == "http://fe80::204:61ff:fe9d:f156/"
// normalize hostname to lower case
uri.hostname('wWw.eXample.Org');
uri.normalizeHostname(); // returns the URI instance for chaining
// uri == "http://www.example.org/"
There is no .normalizeHost(), as .host() is a property comprised of .hostname() and .port()
Removes the port, if it's the default for the given protocol (http: 80, https: 443, ftp: 21).
The list of default ports can be modified at URI.defaultPorts
var uri = new URI("http://example.org:80/foo.html");
// normalize port
uri.normalizePort(); // returns the URI instance for chaining
// uri == "http://example.org/foo.html"
.normalizePath() is an alias of .normalizePathname(), they resolve relative hierarchies
var uri = new URI("/hello/foo/woo/.././../world.html");
// normalize path
uri.normalizePathname(); // returns the URI instance for chaining
// uri == "/hello/world.html"
Turns ?&foo=bar&&foo=bar&foo=baz& into ?foo=bar&foo=baz and removes ? if there is no query string.
var uri = new URI("?&foo=bar&&foo=bar&foo=baz&");
// normalize search
uri.normalizeSearch(); // returns the URI instance for chaining
// uri == "?foo=bar&foo=baz"
removes # if there is no hash
var uri = new URI("http://example.org/foo/hello.html#");
// normalize hash
uri.normalizeHash(); // returns the URI instance for chaining
// uri == "http://example.org/bar/world.xml"
Formats URLs to be human readable (much like your browser does nowadays).
var uri = new URI("http://foo:[email protected]/"
+ "hello%20world/ä.html?foo%5B%5D=b+är#fragment");
u.readable() === "http://www.exämple.org/"
+ "hello world/ä.html?foo[]=b är#fragment";
.relativeTo() compares to paths an makes one relative to the other
var uri = new URI("/relative/path");
// make path relative
var relUri = uri.relativeTo("/relative/sub/foo/sub/file"); // returns a new URI instance
// relUri == "../../../path"
.relativeTo() and .absoluteTo() reverse each other.
.absoluteTo() makes a relative path absolute based on another path
var uri = new URI("../../../path");
// make path absolute
var relUri = uri.absoluteTo("/relative/sub/foo/sub/file"); // returns a new URI instance
// relUri == "/relative/path"
.relativeTo() and .absoluteTo() reverse each other.
.equals() determines if the given URLs are the same - disregarding default ports, capitalization, dot-pathnames, query-parameter order, etc.
var a = "http://example.org/foo/bar.html"
+ "?foo=bar&hello=world&hello=mars#fragment",
b;
// normalizing URI before comparison:
b = "http://exAMPle.org:80/foo/../foo/bar.html"
+ "?foo=bar&hello=world&hello=mars#fragment";
a !== b;
URI(a).equals(b) === true;
// comparing query string parameters:
b = "http://example.org/foo/bar.html"
+ "?hello=mars&foo=bar&hello=world&#fragment";
a !== b;
URI(a).equals(b) === true;
// shorthand for comparing to window.location.href:
URI(a).equals();
parses a string into its URI components. returns an object containing the found components
var result = URI.parse("http://example.org/foo.html");
result === {
protocol: "http",
username: null,
password: null,
hostname: "example.org",
port: null,
path: "/foo.html",
query: null,
fragment: null
};
parses a string's beginning into its URI components username, password, hostname, port.
Found components are appended to the parts parameter.
Remaining string is returned
var parts = {},
result = URI.parseAuthority("user:[email protected]:8080/foo.html", parts);
result === "/foo.html";
parts === {
username: "user",
password: "pass",
hostname: "example.org",
port: "8080"
};
parses a string's beginning into its URI components hostname, port.
Found components are appended to the parts parameter.
Remaining string is returned
var parts = {},
result = URI.parseAuthority("example.org:8080/foo.html", parts);
result === "/foo.html";
parts === {
hostname: "example.org",
port: "8080"
};
Parses the passed query string into an object. Returns object {propertyName: propertyValue}
var result = URI.parseQuery("?foo=bar&hello=world&hello=mars&bam=&yup");
result === {
foo: "bar",
hello: ["world", "mars"],
bam: "",
yup: null
};
serializes the URI components passed in parts into a URI string
var parts = {
protocol: "http",
username: null,
password: null,
hostname: "example.org",
port: null,
path: "/foo.html",
query: null,
fragment: null
};
URI.build(parts) === "http://example.org/foo.html";
serializes the URI components username, password, hostname, port passed in parts into a URI string
var parts = {
username: "user",
password: "pass",
hostname: "example.org",
port: "8080"
};
URI.buildAuthority(parts) === "user:[email protected]:8080";
serializes the URI components hostname, port passed in parts into a URI string
var parts = {
hostname: "example.org",
port: "8080"
};
URI.buildHost(parts) === "example.org:8080";
serializes the query string parameters
var data = {
foo: "bar",
hello: ["world", "mars", "mars"],
bam: "",
yup: null,
removed: undefined
}
// Note: duplicate hello=mars is dropped (default behavior!)
URI.buildQuery(data) === "foo=bar&hello=world&hello=mars&bam=&yup";
// Note: duplicate hello=mars is preserved
URI.buildQuery(data, true) === "foo=bar&hello=world&hello=mars&hello=mars&bam=&yup";
To preserve duplicate values, use URI.buildQuery() directly:
var uri = new URI("http://example.org/foo.html?bar=baz"),
data = uri.query(true);
data.some = "new data";
uri.query(URI.buildQuery(data, true));
// you can also use the static URI.addQuery() and URI.removeQuery()
URI.addQuery(data, "hello", "world");
uri.query(URI.buildQuery(data, true));
adds data to a map
var data = {};
URI.addQuery(data, "hello", "mars");
data === {hello: 'mars'};
URI.addQuery(data, "hello", "world");
data === {hello: ['mars', 'world']};
URI.addQuery(data, {foo: "bar", goodbye : ["world", "mars"]});
data === {hello: ['mars', 'world'], foo: "bar", goodbye : ["world", "mars"]};
removes data from a map
var data === {hello: ['mars', 'world'], foo: "bar", goodbye : ["world", "mars"]};
URI.removeQuery(data, "hello");
data === {foo: "bar", goodbye : ["world", "mars"]};
// remove an attribute with value filter
data = {hello: ["world", "mars"], foo: "bar"};
URI.removeQuery(data, "hello", "world");
data === {hello: ["mars"], foo: "bar"} // yes, still an array
// remove multiple values
data = {hello: ["world", "mars"], foo: "bar", mine: "true"}
URI.removeQuery(["hello", "foo"]);
data === {mine: "true"};
// remove multiple values with value filter
data = {hello: ["world", "mars"], foo: "bar", mine: "true", a: ["1", "2", "3"]}
URI.removeQuery({hello: "world", foo: undefined, a: ["1", "3"]});
data === {hello: ["mars"], mine: "true", a: ["2"]}
URI.commonPath() determines the common base directory of two paths.
URI.commonPath('/foo/bar/baz.html', '/foo/bar/world.html');
// returns "/foo/bar/"
URI.commonPath('/foo/bar/baz.html', '/foo/bazz/world.html');
// returns "/foo/"
URI.commonPath('/foo/bar/baz.html', '/other/world.html');
// returns "/"
URI.commonPath('/foo', 'bar');
// returns ""
URI.withinString() identifies URIs within text, e.g. to translate them to <a>-Tags. (Obviously you'd want to put the urls inside the href-Attribute and escape them properly…)
var source = "Hello www.example.com,\n"
+ "http://google.com is a search engine, like http://www.bing.com\n"
+ "http://exämple.org/foo.html?baz=la#bumm is an IDN URL,\n"
+ "http://123.123.123.123/foo.html is IPv4 and "
+ "http://fe80:0000:0000:0000:0204:61ff:fe9d:f156/foobar.html is IPv6.\n"
+ "links can also be in parens (http://example.org) "
+ "or quotes »http://example.org«.";
var result = URI.withinString(source, function(url) {
// callback needs to return a string
// feel free to URI(url).normalize().toString() or something
return '<a>' + url + '</a>';
});
/* result is:
Hello <a>www.example.com</a>,
<a>http://google.com</a> is a search engine, like <a>http://www.bing.com</a>
<a>http://exämple.org/foo.html?baz=la#bumm</a> is an IDN URL,
<a>http://123.123.123.123/foo.html</a> is IPv4 and <a>http://fe80:0000:0000:0000:0204:61ff:fe9d:f156/foobar.html</a> is IPv6.
links can also be in parens (<a>http://example.org</a>) or quotes »<a>http://example.org</a>«.
*/
// a proper replacement could look like the following:
var escapeHtml = function(string) {
return string
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/"/g, '"');
}
result = URI.withinString(source, function(url) {
var uri = new URI(url);
uri.normalize();
return '<a href="' + escapeHtml(uri) + '">'
+ escapeHtml(url.readable()) + '</a>';
});