我刚刚阅读了关于decodeURI
(MDN,ES6 spec)的内容,引起了我的注意:
不会替换encodeURI无法引入的转义序列。
因此,它应该只解码encodeURI
编码的字符。
// None of these should be escaped by `encodeURI`.
const unescaped = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'();/?:@&=+$,#";
const data = [...unescaped].map(char => ({
"char": char,
"encodeURI(char)": encodeURI(char),
"encodePercent(char)": encodePercent(char),
"decodeURI(encodePercent(char))": decodeURI(encodePercent(char))
}));
console.table( data );
console.log( "Check the browser's console." );
function encodePercent(string) {
return string.replace(/./g, char => "%" + char.charCodeAt(0).toString(16));
}

为什么这只适用于; / ? : @ & = + $ , #
?
答案 0 :(得分:0)
规范说明了以下步骤:
- 让 unescapedURISet 成为一个字符串,其中包含在 uriReserved 和 uriUnescaped 加上“#”
中有效的每个代码单元的一个实例 醇>
让我们看一下uriReserved,然后看一下:
uriReserved :::
之一; / ? : @ & = + $ ,
然后是以下步骤:
- 返回编码(uriString,unescapedURISet)。
醇>
Encode除了 unescapedURISet 中包含; / ? : @ & = + $ ,
的字符外,其他所有内容都会对字符串进行编码。
这意味着encodeURI
永远不会为 uriReserved 和 uriUnescaped 中的任何内容引入转义序列。
有趣的是,decodeURI
定义如下:
让reservedURISet为一个字符串,其中包含在 uriReserved 加上“#”有效的每个代码单元的一个实例。
- 醇>
返回解码(uriString,reservedURISet)。
Decode的工作方式类似于编码和解码除 reservedURISet 中的字符之外的所有内容。显然,只有 uriReserved 的字符被排除在解码之外。那些恰好是; / ? : @ & = + $ ,
!
问题仍然是标准规定的原因。如果他们在 reservedURISet 中包含了 uriUnescaped ,那么行为将完全与导言所述相同。可能是个错误?