加载中…
个人资料
新技术笔记
新技术笔记
  • 博客等级:
  • 博客积分:0
  • 博客访问:409,867
  • 关注人气:197
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

URLEncode编码详解:百分号编码

(2012-04-10 17:07:40)
标签:

百分号编码

urlencode

杂谈

分类: 技术荟萃

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

URI的百分号编码

URI的字符类型

URI所允许的字符分作保留未保留. 保留字符是那些具有特殊含义的字符. 例如, 斜线字符用于URL (或者更一般的, URI)不同部分的分界符. 未保留字符没有这些特殊含义. 百分号编码把保留字符表示为特殊字符序列. 上述情形随URI与URI的不同版本规格会有轻微的变化.

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


RFC 3986 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一个路径成分的内部, 则三字符序列"/"或"/"就用于代替原本的"/"出现在该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的消费者不应该把"A"与"A", "~"与"~"视作不同, 但是某些URI的消费者就是这么做了. 为了最大的互操作性, URI的制造者不应该把未保留字符百分号编码.

对百分号字符的百分号编码

由于百分号字符("%")表示百分号编码字节流的存在, 因此百分号字符应该被编码为3个字节的序列:"%",用于URI内部.

任意数据的百分号编码

大多数URI涉及表示任意数据, 例如IP地址文件系统路径作为URI的成分.

二进数据

1994年发布的RFC 1738规定[1], URI中的二进制数据应该表示为8位元组的序列,然后对每个8位元组按照上述方式百分号编码. 例如,字节值0F (十六进制)应表示为"", 字节值41(十六进制)应表示为"A"或"A". 优先使用未保留字符来表示这些字节值,因为这使得URL更短.

字符数据

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

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

当前标准

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

非标准的实现

T有一些不符合标准的把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方法甚至更古远的email[2]把请求发送给服务器。这里的编码方法采用了一个非常早期的通用的URI百分号编码方法,并且有很多小的修改如新行规范化以及把空格符的编码" "替换为"+" . 按这套方法编码的数据的MIME类型是application/x-www-form-urlencoded, 当前仍用于(虽然非常过时了)HTML与XForms规范中. 此外,CGI规范包括了web服务器如何解码这类数据、利用这类数据的内容.

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

参见

参考文献

  1. ^ RFC 1738 §2.2; RFC 2396 §2.4; RFC 3986 §1.2.1, 2.1, 2.5
  2. ^ User-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.

 

转载地址:http://zh.wikipedia.org/zh-cn/百分号编码

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有