我刚刚阅读了有关decodeURI
(MDN,ES6规范)的内容,有些东西引起了我的注意:
不会替换 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));
}
为什么这只适用于; / ? : @ & = + $ , #
?
规范规定了以下步骤:
- 让unescapedURISet是一个字符串,其中包含在 uriReserved 和uriUnericed中有效的每个代码单元的一个实例加上 "#">
让我们来看看uriReserved,瞧:
uri保留 ::: 其中之一
; / ? : @ & = + $ ,
然后是以下步骤:
- Return Encode(uriString, unescapedURISet).
对字符串进行编码的所有内容进行编码,但未转义 URISet中的字符除外,其中包括; / ? : @ & = + $ ,
.
这意味着encodeURI
永远无法为uriReserved 和 uriUnescape中的任何内容引入转义序列。
有趣的是,decodeURI
是这样定义的:
让 reservedURISet 是一个字符串,其中包含在uriReserved中有效的每个代码单元的一个实例加上"#"。
return Decode(uriString, reservedURISet).
解码的工作方式与编码类似,并解码除保留的 URISet中的字符之外的所有内容。显然,只有uriReserve的字符被排除在解码之外。而那些恰好是; / ? : @ & = + $ ,
!
问题仍然是为什么标准指定了这一点。如果他们在保留的URISet中包含uriUnescaped,那么行为将完全符合介绍中所述。可能是个错误?