百分号编码

百分号编码（），又稱URL编码（）是特定上下文的统一资源定位符（URL）的编码机制，实际上也适用于统一资源标志符（URI）的编码。也用于为application/x-www-form-urlencoded MIME准备数据，因为它用于通过HTTP的请求操作（request）提交HTML表单数据。

 URI的百分号编码 
 URI的字符类型 
URI所允许的字符分作保留与未保留。保留字符是那些具有特殊含义的字符，例如：斜线字符用于URL（或URI）不同部分的分界符；未保留字符没有这些特殊含义。百分号编码把保留字符表示为特殊字符序列。上述情形随URI与URI的不同版本规格会有轻微的变化。

+ section 2.2 保留字符 （2005年1月） !  *  '  (  )  ;  :  @  &  =  +  $  ,  /  ?  #  [  ]

+ section 2.3 未保留字符 （2005年1月） A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z 0  1  2  3  4  5  6  7  8  9 -  _  .  ~  

URI中的其它字符必须用百分号编码。

 对保留字符的百分号编码 
如果一个保留字符在特定上下文中具有特殊含义（称作“reserved purpose”） , 且URI中必须使用该字符用于其它目的，那么该字符必须百分号编码。百分号编码一个保留字符，首先需要把该字符的ASCII的值表示为两个16进制的数字，然后在其前面放置转义字符（“%”），置入URI中的相应位置。（对于非ASCII字符，需要转换为UTF-8字节序，然后每个字节按照上述方式表示。）

例如，"/"，如果用作URI的路径成份的分界符，则是具有特殊含义的保留字符。如果该字符需要出现在URI一个路径成分的内部，则三字符序列"%2F"或"%2f"就用于代替原本的"/"出现在该URI路径成分的内部.

+保留字符的百分号编码 !  #  $   &  '  (  )  *  +  ,  /  :   ;   =  ?  @   [  ] %21  %23  %24   %26  %27  %28  %29  %2A  %2B  %2C  %2F  %3A   %3B   %3D %3F   %40  %5B  %5D

在特定上下文中没有特殊含义的保留字符也可以被百分号编码，在语义上与不百分号编码的该字符没有差别。

在URI的"查询"成分（?字符后的部分）中, 例如"/"仍然是保留字符但是没有特殊含义，除非一个特定的URI有其它规定。该/字符在没有特殊含义时不需要百分号编码。

如果保留字符具有特殊含义，那么该保留字符用百分号编码的URI与该保留字符仅用其自身表示的URI具有不同的语义。

 对未保留字符的百分号编码 
未保留字符不需要百分号编码。

两个URI的差别如果仅在于未保留字符是用百分号编码还是用字符自身表示，那么这两个URI具有等价的语义。但URI处理器实际上并不总是把二者视作等价。例如，URI的消费者不应该把"%41"与"A"，"%7E"与"~"视作不同，但是某些URI的消费者就是这么做了。为了最大的互操作性，URI的制造者不应该对未保留字符进行百分号编码。

 对百分号字符的百分号编码 
由于百分号字符（"%"）表示百分号编码字节流的存在，因此百分号字符应该被编码为3个字节的序列："%25"，用于URI内部。

 对任意数据的百分号编码 
大多数URI涉及表示任意数据，例如IP地址或文件系统路径作为URI的成分。

 二进数据 
1994年发布的规定RFC 1738 §2.2; RFC 2396 §2.4; RFC 3986 §1.2.1, 2.1, 2.5， URI中的二进制数据应该表示为8位元组的序列，然后对每个8位元组按照上述方式百分号编码. 例如，字节值0F（十六进制）应表示为"%0F"，字节值41（十六进制）应表示为"A"或"%41". 优先使用未保留字符来表示这些字节值，因为这使得URL更短。

 字符数据 
二进数据的百分号编码过程已经被外推到字符数据，甚至到不适合或未被完全规范的地步。在WWW初创阶段，仅仅处理ASCII字符是否编码问题，还没有什么问题。但随后发展到对非ASCII字符如何在URI中编码，缺少标准规范的情况下导致了歧义性的解释URI的错误。

例如， 基于RFC 1738与的协议规定，字符数据先要根据某种字符编码转换为字节流，然后再表示为URI。如果URI不提供是何种字符编码的提示信息，那么这个URI难以可靠的解析。

 当前标准 
2005年1月发布的RFC 3986，建议所有新的URI必须对未保留字符不加以百分号编码；其它字符建议先转换为UTF-8字节序列, 然后对其字节值使用百分号编码。此前的URI不受此标准的影响。

 非标准的实现 
有一些不符合标准的把Unicode字符在URI中表示为：%uxxxx, 其中xxxx是用4个十六进制数字表示的Unicode的码位值。任何RFC都没有这样的字符表示方法，并且已经被W3C拒绝 。第三版的ECMA-262仍然包含函数escape(string)使用这种语法，但也有函数encodeURI(uri)转换字符到UTF-8字节序列并用百分号编码每个字节。

application/x-www-form-urlencoded类型

当HTML表单中的数据被提交时，表单的域名与值被编码并通过HTTP的GET或者POST方法甚至更古远的emailUser-agent support for email based HTML form submission, using a 'mailto' URL as the form action, was proposed in RFC 1867 section 5.6, during the HTML 3.2 era. Various web browsers implemented it by invoking a separate email program or using their own rudimentary SMTP capabilities. Although sometimes unreliable, it was briefly popular as a simple way to transmit form data without involving a web server or CGI scripts.把请求发送给服务器。这里的编码方法采用了一个非常早期的通用的URI百分号编码方法，并且有很多小的修改如換行规范化以及把空格符的编码"%20"替换为"+" 。按这套方法编码的数据的MIME类型是application/x-www-form-urlencoded，当前仍用于（虽然非常过时了）HTML与XForms规范中。此外，CGI规范包括了web服务器如何解码这类数据、利用这类数据的内容。

如果发送的是HTTP GET请求，application/x-www-form-urlencoded数据包含在所请求URI的查询成分中。如果发送的是HTTP POST请求或通过email，数据被放置在消息体中，媒体类型的名字被包含在消息的Content-Type头内部。

 参见 
 Quoted-printable

参考文献

 外部链接 

 RFC 3986 / STD 66 (plus errata ), the current generic URI syntax specification.
 RFC 2396 (obsolete, plus errata ) and RFC 2732 (plus errata ) together comprised the previous version of the generic URI syntax specification.
 RFC 1738 (mostly obsolete) and RFC 1808 (obsolete), which define URLs.
 RFC 1630 (obsolete), the first generic URI syntax specification.
 W3C Guidelines on Naming and Addressing: URIs, URLs, ... 
 W3C explanation of UTF-8 in URIs 
 W3C HTML form content types 
 線上URL編解碼工具 

B
B
B