Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4400866
  • 博文数量: 291
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7924
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 14:28
  • 认证徽章:
个人简介

阿里巴巴是个快乐的青年

文章分类

全部博文(291)

文章存档

2018年(21)

2017年(4)

2016年(5)

2015年(17)

2014年(68)

2013年(174)

2012年(2)

分类: Web开发

2014-01-27 22:10:38

        URL之所以要编码,不外乎几个原因,比如:URL中某些字符会引起歧义、URL参数中含有隐私数据、URL中参数中含有中文(URL编码格式采用ASCII而非Unicode)等。
一、参数字符串
        URL参数字符串中使用key=value键值对这样的形式来传递参数,键值对之间以&符号分隔,比如:/ex?i=mm_1_2_3&cb=jsonp_callback。如果value字符串中包含了=或者&,那么就会造成接收URL的服务器解析错误,因此,必须对会引起歧义的符号=和&进行转义,即对其进行编码。
        典型的URL格式如下:
        http://toruk.tanx.com:80/ex?i=mm_35055626_3484594_13482142&cb=jsonp_callback_7498#nose    
        scheme:http://
        authority:toruk.tanx.com:80
        path:/ex
        query:?i=mm_35055626_3484594_13482142&cb=jsonp_callback
        fragment:#nose

二、编解码字符
        RFC3986规定URL中只允许包含英文字母(a-zA-Z)、数字(0-9)、4个特殊字符(-、_、.、~)以及所有保留字符(比如:/、?、[]、@等)。RFC3986对URL编码问题做了详细建议,指出了哪些字符需要编码才不会引起URL语义歧义,以及对这些字符编码的原因。
        URL可以划分为若干组件,比如:协议、主机、路径等,保留字符中有些就是用作分隔不同组件的,比如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数等,还有一些字符用于每个组件内起到分隔作用,比如:=用于分隔查询参数中的key=value,&用于分隔查询参数中的多个键值对等。当组件中的普通数据包含这些特殊字符使,需要对其进行编码。
        RFC3986中指定保留字符包括:!、*、'、()、;、:、@、&、=、+、$、,、/、?、#、[],此外,还有一些字符也不能直接出现在URL中而需要编码,比如:空格、引号、<>、#、%(用作编码时使用的特殊字符)、{}、|、\、^、[]、`、~等。
        总之,URL中如果出现非字母和数字字符时,就去查一下RFC3986文档以确认是否需要编码,而不是靠臆测。

三、编解码方式
        URL编码(URL Encoding)也称为百分号编码(Percent-encoding),即其使用百分号(%)加上两位字符(0123456789ABCDEF)来代表一个字节的十进制形式(即被编码字符),其实就是用%+两个十六进制字符来表示一个字符。URL编码默认使用的字符集是ASCII,例如:字符a在ASCII码中对应的十六进制是0x61(十进制是97),那么URL编码后得到的就是%61。实际中,字符a是不需要编码的。
        对于非ASCII字符,需要使用ASCII字符集的超集进行编码得到相应的字节,然后对每个字节执行百分号编码。
        对于Unicode字符,RFC文档建议使用UTF-8对其进行编码得到相应的字节,然后对每个字节执行百分号编码。例如:“中文”使用UTF-8字符集得到的字节为0xE4、0xB8、0xAD、0xE6、0x96、0x87,经过URL编码之后得到%E4、%B8、%AD、%E6、%96、%87
        关于字符编码ASCII、Unicode和UTF-8之间的关系请参看这里
        各种语言都需要编写自己对应的编码和解码函数,C/C++的可以参见这里。此处,以Javascript为例说明之,Javascript中提供了3对函数用于对URL进行编码和解码,分别是escape/unescape、encodeURIComponent/decodeURIComponent、encodeURI/decodeURI
        escape编码基本已经废弃,后两者使用UTF-8对非ASCII字符进行编码,然后再进行百分号编码,这是RFC推荐使用的方式。
        encodeURIComponent和encodeURI区别在于适用场合不同:encodeURIComponent被用作对URI的一个组件进行编码,而encodeURI被用作对一个完整的URI进行编码。二者编码字符范围不一样,即前者比后者范围大。附上三者无需编解码的字符范围作为结束:
        (1)escape(69个):*、/、@、+、-、.、_、0-9、a-z、A-Z
        (2)encodeURIComponent(71个):!、'、()、*、-、.、_、~、0-9、a-z、A-Z
        (3)encodeURI(82个):!、#、$、&、'、()、*、+、,、/、:、;、=、?、@、-、.、_、~、0-9、a-z、A-Z
        关于Web开发中编解码问题还可以参见这里,关于Web开发的详细知识可以参见这里


阅读(2738) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

scq2099yt2014-01-27 22:10:49

文明上网,理性发言...

评论热议
请登录后评论。

登录 注册