URL编码表
backspace | 8% | A | 41% | a | 61% | § | %A7 | Õ | %D5 | |
tab | 9% | B | 42% | b | 62% | « | %AB | Ö | %D6 | |
linefeed | %0A | C | 43% | c | 63% | ¬ | %AC | Ø | %D8 | |
creturn | %0D | D | 44% | d | 64% | ¯ | %AD | Ù | %D9 | |
space | 20% | E | 45% | e | 65% | º | %B0 | Ú | %DA | |
! | 21% | F | 46% | f | 66% | ± | %B1 | Û | %DB | |
" | 22% | G | 47% | g | 67% | ª | %B2 | Ü | %DC | |
# | 23% | H | 48% | h | 68% | , | %B4 | Ý | %DD | |
$ | 24% | I | 49% | i | 69% | µ | %B5 | Þ | %DE | |
% | 25% | J | %4A | j | %6A | » | %BB | ß | %DF | |
& | 26% | K | %4B | k | %6B | ¼ | %BC | à | %E0 | |
' | 27% | L | %4C | l | %6C | ½ | %BD | á | %E1 | |
( | 28% | M | %4D | m | %6D | ¿ | %BF | â | %E2 | |
) | 29% | N | %4E | n | %6E | À | %C0 | ã | %E3 | |
* | %2A | O | %4F | o | %6F | Á | %C1 | ä | %E4 | |
+ | %2B | P | 50% | p | 70% | Â | %C2 | å | %E5 | |
, | %2C | Q | 51% | q | 71% | Ã | %C3 | æ | %E6 | |
- | %2D | R | 52% | r | 72% | Ä | %C4 | ç | %E7 | |
. | %2E | S | 53% | s | 73% | Å | %C5 | è | %E8 | |
/ | %2F | T | 54% | t | 74% | Æ | %C6 | é | %E9 | |
0 | 30% | U | 55% | u | 75% | Ç | %C7 | ê | %EA | |
1 | 31% | V | 56% | v | 76% | È | %C8 | ë | %EB | |
2 | 32% | W | 57% | w | 77% | É | %C9 | ì | %EC | |
3 | 33% | X | 58% | x | 78% | Ê | %CA | í | %ED | |
4 | 34% | Y | 59% | y | 79% | Ë | %CB | î | %EE | |
5 | 35% | Z | %5A | z | %7A | Ì | %CC | ï | %EF | |
6 | 36% | ð | %F0 | |||||||
7 | 37% | ? | %3F | { | %7B | Í | %CD | ñ | %F1 | |
8 | 38% | @ | 40% | | | %7C | Î | %CE | ò | %F2 | |
9 | 39% | [ | %5B | } | %7D | Ï | %CF | ó | %F3 | |
: | %3A | \ | %5C | ~ | %7E | Ð | %D0 | ô | %F4 | |
; | %3B | ] | %5D | ¢ | %A2 | Ñ | %D1 | õ | %F5 | |
< | %3C | ^ | %5E | £ | %A3 | Ò | %D2 | ö | %F6 | |
= | %3D | _ | %5F | ¥ | %A5 | Ó | %D3 | ÷ | %F7 | |
> | %3E | ` | 60% | | | %A6 | Ô | %D4 | ø | %F8 | |
ù | %F9 |
为什么要进行URL编码!!!
我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割。
如"?name1=value1&name2=value2",这样在服务端在收到这种字符串的时候,会用“&”分割出每一个参数,然后再用“=”来分割出参数值。
针对“name1=value1&name2=value2”我们来说一下客户端到服务端的概念上解析过程:
上述字符串在计算机中用ASCII吗表示为:
现在有这样一个问题,如果我的参数值中就包含=或&这种特殊字符的时候该怎么办?
比如说“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样“name1=va&lu=e1”。我们的本意是就只有一个键值对,但是服务端会解析成两个键值对,这样就产生了奇异。
如何解决上述问题带来的歧义呢?解决的办法就是对参数进行URL编码
另外一个问题,就是为什么我们要用ASCII传输,可不可以用别的编码?
当然可以用别的编码,你自己可以开发一套编码,然后自己解析。就像大部分国家都有自己的语言一样。那国家之间要交流,怎么办?用英语把,英语的使用范围最广。
通常如果一样东西需要编码,说明这样东西并不适合传输。原因多种多样,如Size过大,包含隐私数据,对于Url来说,之所以要进行编码,是因为Url中有些字符会引起歧义。
Url编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。
预备知识:URI是统一资源标识的意思,通常我们所说的URL只是URI的一种。典型URL的格式如下所示。下面提到的URL编码,实际上应该指的是URI编码。
哪些字符需要编码
RFC3986文档规定,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。RFC3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。
-
US-ASCII字符集中没有对应的可打印字符:Url中只允许使用可打印字符。US-ASCII码中的10-7F字节全都表示控制字符,这些字符都不能直接出现在Url中。同时,对于80-FF字节(ISO-8859-1),由于已经超出了US-ACII定义的字节范围,因此也不可以放在Url中。搜索公众号互联网架构师复“2T”,送你一份惊喜礼包。
-
保留字符:Url可以划分成若干个组件,协议、主机、路径等。有一些字符(:/?#[]@)是用作分隔不同组件的。例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数,等等。
还有一些字符(!><'()*+,;=)用于在每个组件中起到分隔作用的,如=用于表示查询参数中的键值对,&符号用于分隔查询多个键值对。当组件中的普通数据包含这些特殊字符时,需要对其进行编码。
但是由于历史原因,目前尚存在一些不标准的编码实现。例如对于符号,虽然RFC3986文档规定,对于波浪符号,不需要进行Url编码,但是还是有很多老的网关或者传输代理会进行编码。
如何对Url中的非法字符进行编码
Url编码通常也被称为百分号编码(Url Encoding,also known as percent-encoding),是因为它的编码方式非常简单,使用%百分号加上两位的字符——0123456789ABCDEF——代表一个字节的十六进制形式。
Url编码默认使用的字符集是US-ASCII。例如a在US-ASCII码中对应的字节是0x61,那么Url编码之后得到的就是%61,我们在地址栏上输入http://g.cn/search?q=%61%62%63,实际上就等同于在google上搜索abc了。又如@符号在ASCII字符集中对应的字节为0x40,经过Url编码之后得到的是%40。