
1.1.2 浏览器URI编码
1.百分号编码
URI编码使用的是百分号编码(Percent-encoding)。对于需要编码的字符,将其表示为两个十六进制的数字,然后在其前面放置转义字符“%”,并替换原字符相应位置进行编码。
RFC3986文档规定,URI中只允许包含未保留字符及所有保留字符。其中,未保留字符包含英文字母(a~z,A~Z),数字(0~9),-、_、.、~4个特殊字符,共66个。对于未保留字符,不需要进行百分号编码。保留字符是那些具有特殊含义的字符。RFC 3986 文档中规定了18个保留字符:

在URI中,保留字符有特殊的意义,如“?”表示查询,“#”表示片段标识。如果希望保留字符不表示特定的意义,仅表示一般字符,那么需要对保留字符进行URL编码。例如,“/”作为保留字符具有特殊意义,即作为URI的路径分隔符,如果希望其不作为URI的路径分隔符,仅作为一般字符,则需编码为"%2F"或"%2f"。
2.encodeURI
encodeURI是W3C的标准(RFC 3986),不对ASCII字母和数字进行编码,不对20个ASCII标点符号(-、_、.、!、~、*、'、(、)、;、/、?、:、@、&、=、+、$、,、#)进行编码。对于66个未保留字符,18个保留字符,除去2个不安全的保留字符“[”“]”,encodeURI的不编码集为82个。
对于非ASCII字符,encodeURI需要将其转换为UTF-8编码字节序,然后在每个字节前面放置转义字符(%)进行百分号编码,并置入URI中的相应位置。

UTF-8:UTF-8具有无字节序要求、单字节特性节约内存、向后兼容ASCII、错误兼容性好等优点。一个纯ASCII字符串也是一个合法的UTF-8字符串,所以现存的ASCII文本不需要转换。为传统的扩展ASCII字符集设计的软件通常可以不经修改或经过很少修改就能与UTF-8一起使用。
3.encodeURIComponent
encodeURIComponent假定参数是URI的一部分(比如协议、主机名、路径或查询字符串),因此,encodeURIComponent将转义除字母、数字、“(”、“)”、“.”、“!”、“~”、“*”、“'”、“-”和“_”外的所有字符。例如,对“name=va&lu=”进行encodeURIComponent编码后结果为“"name%3Dva%26lu%3D"”。对于URL组成部分中的特殊字符,通常需要使用encodeURIComponent进行编码,如:

使用encodeURIComponent的好处是,如果字符串被发送到服务端进行解析,那么服务端会把紧跟在“%”后的字节当成普通的字节,而不会把它当成各个参数或键值对的分隔符。
相比encodeURIComponent,encodeURI被用作对一个完整的URI进行编码,而encodeURIComponent则被用作对URI的一个组件或者URI中的一个片段进行编码。从上面的编码示例来看,encodeURIComponent编码的字符范围要比encodeURI大。