在JavaScript中,URL
构造函数在查询字符串中不编码括号和括号,而encodeURI
或encodeURIComponent
总是编码它们。这让我感到困惑,因为大多数来源都说,当查询参数包含使用encodeURI
/encodeURIComponent
的特殊字符时,对它们进行编码。我希望URL
对象具有类似的行为。
这使我在编写单元测试时遇到问题,因为我不知道URL对象的查询参数将如何编码。是否有一个规范,或者我应该总是编码我的参数之前使用URL
构造函数?谢谢你的帮助。
示例显示URL对象在查询字符串
中不编码括号const href = (new URL('https://foobar.com?myQuery={"@asdf/asdf":"1234"}')).href;
// ^ https://foobar.com/?myQuery={%22@asdf/asdf%22:%221234%22}
如果我使用encodeURI
,唯一的区别是括号被编码为
const href = encodeURI('https://foobar.com?myQuery={"@asdf/asdf":"1234"}');
// ^ https://foobar.com?myQuery=%7B%22@asdf/asdf%22:%221234%22%7D
注意:如果URL对象不在查询参数中,则对括号进行编码。
const href = (new URL('https://foobar.com/}}}?myQuery={"@asdf/asdf":"1234"}')).href;
// ^ https://foobar.com/%7D%7D%7D?myQuery={%22@asdf/asdf%22:%221234%22}
可能存在多个编码,所有编码都应该被解释为同一个url,因此从技术上讲没有一个是错误的。另一个例子是百分比编码可以用大写或小写字符(%aa
或%AA
)完成,并且域是不区分大小写的,空格可能被编码(在某些部分)为+
或%20
。
如果你想对一个特定的URL编码器实现进行单元测试,你可以匹配字符串,但是如果你想知道两个URL是否相同不管是如何编码的,你首先需要在比较之前经历一个叫做"规范化"的步骤。