为什么decodeURI会解码比它应该更多的字符?

时间:2017-04-07 14:13:29

标签: javascript urlencode

我刚刚阅读了关于decodeURIMDNES6 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));
}




为什么这只适用于; / ? : @ & = + $ , #

1 个答案:

答案 0 :(得分:0)

规范说明了以下步骤:

  
      
  1. unescapedURISet 成为一个字符串,其中包含在 uriReserved uriUnescaped 加上“#”
  2. 中有效的每个代码单元的一个实例   

让我们看一下uriReserved,然后看一下:

  

uriReserved :::

之一
; / ? : @ & = + $ ,

然后是以下步骤:

  
      
  1. 返回编码(uriString,unescapedURISet)。
  2.   

Encode除了 unescapedURISet 中包含; / ? : @ & = + $ ,的字符外,其他所有内容都会对字符串进行编码。

这意味着encodeURI永远不会为 uriReserved uriUnescaped 中的任何内容引入转义序列。

有趣的是,decodeURI定义如下:

  
      
  1. 让reservedURISet为一个字符串,其中包含在 uriReserved 加上“#”有效的每个代码单元的一个实例。

  2.   
  3. 返回解码(uriString,reservedURISet)。

  4.   

Decode的工作方式类似于编码和解码除 reservedURISet 中的字符之外的所有内容。显然,只有 uriReserved 的字符被排除在解码之外。那些恰好是; / ? : @ & = + $ ,

问题仍然是标准规定的原因。如果他们在 reservedURISet 中包含了 uriUnescaped ,那么行为将完全与导言所述相同。可能是个错误?