|
| 1 | +| Title | Implement WHATWG URL Spec | |
| 2 | +|--------|-----------------------------| |
| 3 | +| Author | @jasnell | |
| 4 | +| Status | DRAFT | |
| 5 | +| Date | 2016-08-11T10:00:00-07:00 | |
| 6 | + |
| 7 | +## Description |
| 8 | + |
| 9 | +The [WHATWG URL Standard](https://url.spec.whatwg.org/) specifies updated |
| 10 | +syntax, parsing and serialization of URLs as currently implemented by the main |
| 11 | +Web Browsers. The existing Node.js `url` module parsing and serialization |
| 12 | +implementation currently does not support the URL standard and fails to pass |
| 13 | +about 160 of the WHATWG URL parsing tests. |
| 14 | + |
| 15 | +This proposal is to implement the WHATWG URL Standard by modifying the existing |
| 16 | +`url` module to provide an implementation of the `URL` object and associated |
| 17 | +APIs as defined by the WHATWG URL Parsing specification. Doing so improves the |
| 18 | +robustness of URL parsing, provides consistency with browser JS code, and can |
| 19 | +eventually allow the reduction of node.js specific APIs. |
| 20 | + |
| 21 | +Initially, the implementation would be introduced as an *undocumented* |
| 22 | +experimental feature exposed via a new `URL` property in the `url` module. |
| 23 | + |
| 24 | +*Note*: In Browser implementations, the `URL` constructor is a global. In the |
| 25 | +initial Node.js implementation, the `URL` constructor would **not** be a |
| 26 | +global; instead, it would be accessible via the `url` module (e.g. |
| 27 | +`const URL = require('url').URL`). |
| 28 | + |
| 29 | +Because the existing `require('url')` module remains otherwise unmodified, |
| 30 | +there should be no backwards compatibility concerns. Once the performance of |
| 31 | +the new URL implementation is on par with the existing `url.parse()` |
| 32 | +implementation, `url.parse()` will go through a normal deprecation cycle and |
| 33 | +the new URL implementation will become a fully documentation and supported |
| 34 | +feature. |
| 35 | + |
| 36 | +The current implementation can be found at: |
| 37 | + |
| 38 | +https://github.com/nodejs/node/pull/7448 |
| 39 | + |
| 40 | +## Example |
| 41 | + |
| 42 | +```js |
| 43 | +const URL = require('url').URL; |
| 44 | +const url = new URL( 'http://user:[email protected]:1234/p/a/t/h?xyz=abc#hash'); |
| 45 | + |
| 46 | +console.log(url.protocol); // http: |
| 47 | +console.log(url.username); // user |
| 48 | +console.log(url.password); // password |
| 49 | +console.log(url.host); // example.org:1234 |
| 50 | +console.log(url.hostname); // example.org |
| 51 | +console.log(url.port); // 1234 |
| 52 | +console.log(url.pathname); // /p/a/t/h |
| 53 | +console.log(url.search); // ?xyz=abc |
| 54 | +console.log(url.searchParams); // SearchParams object |
| 55 | +console.log(url.hash); // hash |
| 56 | + |
| 57 | +// The SearchParams object is defined by the WHATWG spec also |
| 58 | +url.searchParams.append('key', 'value'); |
| 59 | + |
| 60 | +console.log(url); |
| 61 | + // http://user:[email protected]:1234/p/a/t/h?xyz=abc&key=value#hash |
| 62 | + |
| 63 | + |
| 64 | +// Example using a base URL |
| 65 | +const url2 = new URL('/foo', url); |
| 66 | +console.log(url.protocol); // http: |
| 67 | +console.log(url.username); // user |
| 68 | +console.log(url.password); // password |
| 69 | +console.log(url.host); // example.org:1234 |
| 70 | +console.log(url.hostname); // example.org |
| 71 | +console.log(url.port); // 1234 |
| 72 | +console.log(url.pathname); // /foo |
| 73 | +console.log(url.search); // '' |
| 74 | +console.log(url.searchParams); // SearchParams object |
| 75 | +console.log(url.hash); // '' |
| 76 | +``` |
| 77 | + |
| 78 | +## APIs |
| 79 | + |
| 80 | +The public API would be as defined by the |
| 81 | +[WHATWG spec](https://url.spec.whatwg.org/#api). |
| 82 | + |
| 83 | +### `new URL(href, base)` |
| 84 | + |
| 85 | +The constructor implements the WHATWG basic parsing algorithm. Accessible via |
| 86 | +`const URL = require('url').URL` |
| 87 | + |
| 88 | +* `href` is a `string` containing the URL to parse. |
| 89 | +* `base` is either a `string` or a `URL` that contains the base URL to resolve |
| 90 | + against while parsing. |
| 91 | + |
| 92 | +See https://url.spec.whatwg.org/#urlutils-members for detail on the properties |
| 93 | +of the `URL` object. |
| 94 | + |
| 95 | +#### `url.protocol` |
| 96 | + |
| 97 | +* Returns a string |
| 98 | +* Getter/Setter |
| 99 | + |
| 100 | +#### `url.username` |
| 101 | + |
| 102 | +* Returns a string |
| 103 | +* Getter/Setter |
| 104 | + |
| 105 | +#### `url.password` |
| 106 | + |
| 107 | +* Returns a string |
| 108 | +* Getter/Setter |
| 109 | + |
| 110 | +#### `url.host` |
| 111 | + |
| 112 | +* Returns a string |
| 113 | +* Getter/Setter |
| 114 | + |
| 115 | +#### `url.hostname` |
| 116 | + |
| 117 | +* Returns a string |
| 118 | +* Getter/Setter |
| 119 | + |
| 120 | +#### `url.port` |
| 121 | + |
| 122 | +* Returns an integer |
| 123 | +* Getter/Setter |
| 124 | + |
| 125 | +#### `url.pathname` |
| 126 | + |
| 127 | +* Returns a string |
| 128 | +* Getter/Setter |
| 129 | + |
| 130 | +#### `url.search` |
| 131 | + |
| 132 | +* Returns a string |
| 133 | +* Getter/Setter |
| 134 | + |
| 135 | +#### `url.searchParams` |
| 136 | + |
| 137 | +* Returns a URLSearchParams object |
| 138 | +* Getter |
| 139 | + |
| 140 | +#### `url.hash` |
| 141 | + |
| 142 | +* Returns a string |
| 143 | +* Getter/Setter |
| 144 | + |
| 145 | +#### `url.origin` |
| 146 | + |
| 147 | +* Returns a string |
| 148 | +* Getter |
| 149 | + |
| 150 | +#### `url.href` |
| 151 | + |
| 152 | +* Returns a string |
| 153 | +* Getter |
| 154 | + |
| 155 | +#### `url.toString()` |
| 156 | + |
| 157 | +* Returns a string (same as `url.href`) |
| 158 | + |
| 159 | +### `URLSearchParams` |
| 160 | + |
| 161 | +Returned by the `url.searchParams` property and provides access read and write |
| 162 | +access to the search params. It is defined at |
| 163 | +https://url.spec.whatwg.org/#interface-urlsearchparams. |
| 164 | + |
| 165 | +Accessible via `require('url').URLSearchParams` |
| 166 | + |
| 167 | +#### `searchParams.append(name, value)` |
| 168 | +#### `searchParams.delete(name)` |
| 169 | +#### `searchParams.get(name)` |
| 170 | +#### `searchParams.getAll(name)` |
| 171 | +#### `searchParams.has(name)` |
| 172 | +#### `searchParams.set(name, value)` |
| 173 | +#### `searchParams.*[Symbol.iterator]()` |
| 174 | +#### `searchParams.toString()` |
| 175 | + |
| 176 | +### `URL.domainToASCII(domain)` |
| 177 | +### `URL.domainToUnicode(domain)` |
0 commit comments