From ea3a68f74f2041207caa30496d9371e2f82cb74a Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 4 May 2020 10:33:51 -0700 Subject: [PATCH] doc: doc and test URLSearchParams discrepancy The WHATWG URL spec is not going to change this behavior so let's document it Signed-off-by: James M Snell Fixes: https://github.com/nodejs/node/issues/33037 PR-URL: https://github.com/nodejs/node/pull/33236 Reviewed-By: Luigi Pinca Reviewed-By: Rich Trott Reviewed-By: Joyee Cheung Reviewed-By: Zeyu Yang --- doc/api/url.md | 24 ++++++++++++++++--- ...twg-url-custom-searchparams-stringifier.js | 9 +++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/doc/api/url.md b/doc/api/url.md index 6950c92f0980c8..3da8adbe8568d2 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -472,9 +472,27 @@ and [`url.format()`][] methods would produce. * {URLSearchParams} Gets the [`URLSearchParams`][] object representing the query parameters of the -URL. This property is read-only; to replace the entirety of query parameters of -the URL, use the [`url.search`][] setter. See [`URLSearchParams`][] -documentation for details. +URL. This property is read-only but the `URLSearchParams` object it provides +can be used to mutate the URL instance; to replace the entirety of query +parameters of the URL, use the [`url.search`][] setter. See +[`URLSearchParams`][] documentation for details. + +Use care when using `.searchParams` to modify the `URL` because, +per the WHATWG specification, the `URLSearchParams` object uses +different rules to determine which characters to percent-encode. For +instance, the `URL` object will not percent encode the ASCII tilde (`~`) +character, while `URLSearchParams` will always encode it: + +```js +const myUrl = new URL('https://example.org/abc?foo=~bar'); + +console.log(myUrl.search); // prints ?foo=~bar + +// Modify the URL via searchParams... +myUrl.searchParams.sort(); + +console.log(myUrl.search); // prints ?foo=%7Ebar +``` #### `url.username` diff --git a/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js b/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js index 1fe936f5e293ab..35307fa914975a 100644 --- a/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js +++ b/test/parallel/test-whatwg-url-custom-searchparams-stringifier.js @@ -16,3 +16,12 @@ const URLSearchParams = require('url').URLSearchParams; message: 'Value of "this" must be of type URLSearchParams' }); } + +// The URLSearchParams stringifier mutates the base URL using +// different percent-encoding rules than the URL itself. +{ + const myUrl = new URL('https://example.org?foo=~bar'); + assert.strictEqual(myUrl.search, '?foo=~bar'); + myUrl.searchParams.sort(); + assert.strictEqual(myUrl.search, '?foo=%7Ebar'); +}