- From: Domenic Denicola <notifications@github.com>
- Date: Mon, 04 May 2020 18:26:46 +0000 (UTC)
- To: whatwg/url <url@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/url/issues/491@github.com>
### Problem See background in #18 and #478. `URLSearchParams` was designed, not to hold URL query data, but instead to hold `application/x-www-form-urlencoded` data, i.e. the data that is sent to a server when submitting a HTML `<form>`. Unfortunately, it was misnamed `URLSearchParams` instead of `ApplicationXWWWFormURLEncodedParams`. And, even more unfortunately, a property named `searchParams` was added to the `URL` class, which is an instance of the `URLSearchParams` class. Any attempts to use the `searchParams` class will give misleading information about the URL. And any attempts to manipulate it will change the contents of your URL's query string in unintended ways, converting values from a query string serialization (of the type produced by the URL parser) into an `application/x-www-form-urlencoded` serialization. Some examples of how `url.searchParams` does not allow faithful introspection into the URL record: ```js let a = 'http://localhost:9999/segment?foo=bar/baz? boo'; let b = 'http://localhost:9999/segment?foo=bar%2Fbaz%3F%20boo'; let urlA = new URL(a); let urlB = new URL(b); // Not equal: console.log(urlA.href); // "http://localhost:9999/segment?foo=bar/baz?%20boo" console.log(urlB.href); // "http://localhost:9999/segment?foo=bar%2Fbaz%3F%20boo" console.log(urlA.search); // "?foo=bar/baz?%20boo" console.log(urlB.search); // "?foo=bar%2Fbaz%3F%20boo" // Equal: console.log(urlA.searchParams.get("foo")); // "bar/baz? boo" console.log(urlB.searchParams.get("foo")); // "bar/baz? boo" // Equal, but both different from search: console.log(urlA.searchParams.toString()); // "foo=bar%2Fbaz%3F+boo" console.log(urlB.searchParams.toString()); // "foo=bar%2Fbaz%3F+boo" ``` Some examples of how using `url.searchParams` for mutation will cause unintended changes to your URL record: ```js const url = new URL('http://httpbin.org/anything?a=~'); console.log(url.href); // "http://httpbin.org/anything?a=~" console.log(url.search); // "?a=~" // This should be a no-op, but it is not: url.searchParams.set("a", url.searchParams.get("a")); console.log(url.href); // "http://httpbin.org/anything?a=%7E" ``` ### Solution In https://github.com/whatwg/url/issues/478#issuecomment-620929779 I proposed four solutions to this problem. In response, @ricea (Chromium) and @achristensen07 indicated they were "in favor of maintaining the status quo". I interpret this as meaning that any changes to either the URL query string parser/serializer, or the `application/x-www-form-urlencoded` parser/serializer, or the `URLSearchParams` class and `url.searchParams` member, are not on the table. Given these constraints, it seems the only thing we could do is propose a new non-breaking addition to the API. As such, I propose a `URLQueryParams` class and a corresponding `url.queryParams` member, which are identical to `URLSearchParams` and `url.searchParams`, except that they use the URL parsing/serialization rules instead of the `application/x-www-form-urlencoded` rules. (Alternate names include `url.realSearchParams` or `url.searchParams2`.) With that added, we could effectively deprecate `url.searchParams` (i.e., state loudly in the spec and MDN that using it will give unreliable results and mess up your URLs), and note that `URLSearchParams` is useful for representing `<form>` serialization, but not useful for manipulating URL search parameters. -- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/whatwg/url/issues/491
Received on Monday, 4 May 2020 18:27:00 UTC