1 | # URI.js
|
2 |
|
3 | URI.js is an [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt) compliant, scheme extendable URI parsing/validating/resolving library for all JavaScript environments (browsers, Node.js, etc).
|
4 | It is also compliant with the IRI ([RFC 3987](http://www.ietf.org/rfc/rfc3987.txt)), IDNA ([RFC 5890](http://www.ietf.org/rfc/rfc5890.txt)), IPv6 Address ([RFC 5952](http://www.ietf.org/rfc/rfc5952.txt)), IPv6 Zone Identifier ([RFC 6874](http://www.ietf.org/rfc/rfc6874.txt)) specifications.
|
5 |
|
6 | URI.js has an extensive test suite, and works in all (Node.js, web) environments. It weighs in at 6.4kb (gzipped, 17kb deflated).
|
7 |
|
8 | ## API
|
9 |
|
10 | ### Parsing
|
11 |
|
12 | URI.parse("uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body");
|
13 | //returns:
|
14 | //{
|
15 | // scheme : "uri",
|
16 | // userinfo : "user:pass",
|
17 | // host : "example.com",
|
18 | // port : 123,
|
19 | // path : "/one/two.three",
|
20 | // query : "q1=a1&q2=a2",
|
21 | // fragment : "body"
|
22 | //}
|
23 |
|
24 | ### Serializing
|
25 |
|
26 | URI.serialize({scheme : "http", host : "example.com", fragment : "footer"}) === "http://example.com/#footer"
|
27 |
|
28 | ### Resolving
|
29 |
|
30 | URI.resolve("uri://a/b/c/d?q", "../../g") === "uri://a/g"
|
31 |
|
32 | ### Normalizing
|
33 |
|
34 | URI.normalize("HTTP://ABC.com:80/%7Esmith/home.html") === "http://abc.com/~smith/home.html"
|
35 |
|
36 | ### Comparison
|
37 |
|
38 | URI.equal("example://a/b/c/%7Bfoo%7D", "eXAMPLE://a/./b/../b/%63/%7bfoo%7d") === true
|
39 |
|
40 | ### IP Support
|
41 |
|
42 | //IPv4 normalization
|
43 | URI.normalize("//192.068.001.000") === "//192.68.1.0"
|
44 |
|
45 | //IPv6 normalization
|
46 | URI.normalize("//[2001:0:0DB8::0:0001]") === "//[2001:0:db8::1]"
|
47 |
|
48 | //IPv6 zone identifier support
|
49 | URI.parse("//[2001:db8::7%25en1]");
|
50 | //returns:
|
51 | //{
|
52 | // host : "2001:db8::7%en1"
|
53 | //}
|
54 |
|
55 | ### IRI Support
|
56 |
|
57 | //convert IRI to URI
|
58 | URI.serialize(URI.parse("http://examplé.org/rosé")) === "http://xn--exampl-gva.org/ros%C3%A9"
|
59 | //convert URI to IRI
|
60 | URI.serialize(URI.parse("http://xn--exampl-gva.org/ros%C3%A9"), {iri:true}) === "http://examplé.org/rosé"
|
61 |
|
62 | ### Options
|
63 |
|
64 | All of the above functions can accept an additional options argument that is an object that can contain one or more of the following properties:
|
65 |
|
66 | * `scheme` (string)
|
67 |
|
68 | Indicates the scheme that the URI should be treated as, overriding the URI's normal scheme parsing behavior.
|
69 |
|
70 | * `reference` (string)
|
71 |
|
72 | If set to `"suffix"`, it indicates that the URI is in the suffix format, and the validator will use the option's `scheme` property to determine the URI's scheme.
|
73 |
|
74 | * `tolerant` (boolean, false)
|
75 |
|
76 | If set to `true`, the parser will relax URI resolving rules.
|
77 |
|
78 | * `absolutePath` (boolean, false)
|
79 |
|
80 | If set to `true`, the serializer will not resolve a relative `path` component.
|
81 |
|
82 | * `iri` (boolean, false)
|
83 |
|
84 | If set to `true`, the serializer will unescape non-ASCII characters as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt).
|
85 |
|
86 | * `unicodeSupport` (boolean, false)
|
87 |
|
88 | If set to `true`, the parser will unescape non-ASCII characters in the parsed output as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt).
|
89 |
|
90 | * `domainHost` (boolean, false)
|
91 |
|
92 | If set to `true`, the library will treat the `host` component as a domain name, and convert IDNs (International Domain Names) as per [RFC 5891](http://www.ietf.org/rfc/rfc5891.txt).
|
93 |
|
94 | ## Scheme Extendable
|
95 |
|
96 | URI.js supports inserting custom [scheme](http://en.wikipedia.org/wiki/URI_scheme) dependent processing rules. Currently, URI.js has built in support for the following schemes:
|
97 |
|
98 | * http \[[RFC 2616](http://www.ietf.org/rfc/rfc2616.txt)\]
|
99 | * https \[[RFC 2818](http://www.ietf.org/rfc/rfc2818.txt)\]
|
100 | * ws \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\]
|
101 | * wss \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\]
|
102 | * mailto \[[RFC 6068](http://www.ietf.org/rfc/rfc6068.txt)\]
|
103 | * urn \[[RFC 2141](http://www.ietf.org/rfc/rfc2141.txt)\]
|
104 | * urn:uuid \[[RFC 4122](http://www.ietf.org/rfc/rfc4122.txt)\]
|
105 |
|
106 | ### HTTP/HTTPS Support
|
107 |
|
108 | URI.equal("HTTP://ABC.COM:80", "http://abc.com/") === true
|
109 | URI.equal("https://abc.com", "HTTPS://ABC.COM:443/") === true
|
110 |
|
111 | ### WS/WSS Support
|
112 |
|
113 | URI.parse("wss://example.com/foo?bar=baz");
|
114 | //returns:
|
115 | //{
|
116 | // scheme : "wss",
|
117 | // host: "example.com",
|
118 | // resourceName: "/foo?bar=baz",
|
119 | // secure: true,
|
120 | //}
|
121 |
|
122 | URI.equal("WS://ABC.COM:80/chat#one", "ws://abc.com/chat") === true
|
123 |
|
124 | ### Mailto Support
|
125 |
|
126 | URI.parse("mailto:alpha@example.com,bravo@example.com?subject=SUBSCRIBE&body=Sign%20me%20up!");
|
127 | //returns:
|
128 | //{
|
129 | // scheme : "mailto",
|
130 | // to : ["alpha@example.com", "bravo@example.com"],
|
131 | // subject : "SUBSCRIBE",
|
132 | // body : "Sign me up!"
|
133 | //}
|
134 |
|
135 | URI.serialize({
|
136 | scheme : "mailto",
|
137 | to : ["alpha@example.com"],
|
138 | subject : "REMOVE",
|
139 | body : "Please remove me",
|
140 | headers : {
|
141 | cc : "charlie@example.com"
|
142 | }
|
143 | }) === "mailto:alpha@example.com?cc=charlie@example.com&subject=REMOVE&body=Please%20remove%20me"
|
144 |
|
145 | ### URN Support
|
146 |
|
147 | URI.parse("urn:example:foo");
|
148 | //returns:
|
149 | //{
|
150 | // scheme : "urn",
|
151 | // nid : "example",
|
152 | // nss : "foo",
|
153 | //}
|
154 |
|
155 | #### URN UUID Support
|
156 |
|
157 | URI.parse("urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
|
158 | //returns:
|
159 | //{
|
160 | // scheme : "urn",
|
161 | // nid : "uuid",
|
162 | // uuid : "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
|
163 | //}
|
164 |
|
165 | ## Usage
|
166 |
|
167 | To load in a browser, use the following tag:
|
168 |
|
169 | <script type="text/javascript" src="uri-js/dist/es5/uri.all.min.js"></script>
|
170 |
|
171 | To load in a CommonJS/Module environment, first install with npm/yarn by running on the command line:
|
172 |
|
173 | npm install uri-js
|
174 | # OR
|
175 | yarn add uri-js
|
176 |
|
177 | Then, in your code, load it using:
|
178 |
|
179 | const URI = require("uri-js");
|
180 |
|
181 | If you are writing your code in ES6+ (ESNEXT) or TypeScript, you would load it using:
|
182 |
|
183 | import * as URI from "uri-js";
|
184 |
|
185 | Or you can load just what you need using named exports:
|
186 |
|
187 | import { parse, serialize, resolve, resolveComponents, normalize, equal, removeDotSegments, pctEncChar, pctDecChars, escapeComponent, unescapeComponent } from "uri-js";
|
188 |
|
189 | ## Breaking changes
|
190 |
|
191 | ### Breaking changes from 3.x
|
192 |
|
193 | URN parsing has been completely changed to better align with the specification. Scheme is now always `urn`, but has two new properties: `nid` which contains the Namspace Identifier, and `nss` which contains the Namespace Specific String. The `nss` property will be removed by higher order scheme handlers, such as the UUID URN scheme handler.
|
194 |
|
195 | The UUID of a URN can now be found in the `uuid` property.
|
196 |
|
197 | ### Breaking changes from 2.x
|
198 |
|
199 | URI validation has been removed as it was slow, exposed a vulnerabilty, and was generally not useful.
|
200 |
|
201 | ### Breaking changes from 1.x
|
202 |
|
203 | The `errors` array on parsed components is now an `error` string.
|