JavaScript `URL`: 设置 pathname 时什么时候编码?

JavaScript `URL`: when to encode when setting `pathname`?

设置 URL 的路径名时,应何时对要设置的值进行编码?

当我说 URL 我的意思是 API: https://developer.mozilla.org/en-US/docs/Web/API/URL

当我说“设置路径名”时,我的意思是这样做:

url.pathname = 'some/path/to/a/resource.html';

根据 MDN 文档,我认为答案是“您不需要”,因为 example 涵盖了这种情况:

URLs are encoded according to the rules found in RFC 3986. For instance:

url.pathname = 'démonstration.html';
console.log(url.href); // "http://www.example.com/d%C3%A9monstration.html"

但是,我遇到了 运行 的情况,似乎我确实需要将我设置的值 pathname 编码为:

url.pathname = 'atest/New Folder1234/!@#$%^&*().html';
console.log(url.href);

我希望它输出: http://example.com/atest/New%20Folder1234/!%40%23%24%25%5E%26*().html

但是我得到的是: https://example.com/atest/New%20Folder1234/!@%23$%^&*().html

似乎得到了我期望的结果:

url.pathname = 'atest/New Folder1234/!@#$%^&*()'.split('/').map(encodeURIComponent).join('/')

这是怎么回事?我在 MDN 文档页面上找不到任何关于 URLpathname 的解释。我快速浏览了 RFC 3986,但这似乎只是描述了 URI 语法。我有 运行 一些实验,试图找到解决这个问题的某种模式,但没有什么特别突出的。

参见 path state 的规范,特别是...

UTF-8 percent-encode c using the path percent-encode set and append the result to buffer.

path percent-encode set 被定义为...

the query percent-encode set and U+003F (?), U+0060 (`), U+007B ({), and U+007D (}).

并且 query percent-encode set 正在...

the C0 control percent-encode set and U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), and U+003E (>).

如果你愿意,你可以继续潜入rabbit-hole,但我觉得这就足够了

请注意,这些集合中的 none 个包含 @$%^& 个您指出的字符。

将这些与 Encode 的规范进行比较,后者更加彻底。