欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

为什么要进行 URL 编码???

程序员文章站 2023-01-28 10:37:34
作者:降瑞雪 cnblogs.com/jerrysion/p/5522673.html 我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割。 如"?name1=value1&name2=value2",这样在服务端在收到这种 ......

作者:降瑞雪
cnblogs.com/jerrysion/p/5522673.html

为什么要进行 URL 编码???

我们都知道http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割。

如"?name1=value1&name2=value2",这样在服务端在收到这种字符串的时候,会用“&”分割出每一个参数,然后再用“=”来分割出参数值。

针对“name1=value1&name2=value2”我们来说一下客户端到服务端的概念上解析过程:

上述字符串在计算机中用ascii吗表示为:

6e616d6531 3d 76616c756531 26 6e616d6532 3d 76616c756532。6e616d6531:name1    3d:=    76616c756531:value1    26:&   6e616d6532:name2    3d:=    76616c756532:value2

服务端在接收到该数据后就可以遍历该字节流,首先一个字节一个字节的吃,当吃到3d这字节后,服务端就知道前面吃得字节表示一个key,再想后吃,如果遇到26,说明从刚才吃的3d到26子节之间的是上一个key的value,以此类推就可以解析出客户端传过来的参数。

现在有这样一个问题,如果我的参数值中就包含=或&这种特殊字符的时候该怎么办?

比如说“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样“name1=va&lu=e1”。我们的本意是就只有一个键值对,但是服务端会解析成两个键值对,这样就产生了奇异。

如何解决上述问题带来的歧义呢?解决的办法就是对参数进行url编码

url编码只是简单的在特殊字符的各个字节前加上%,例如,我们对上述会产生奇异的字符进行url编码后结果:“name1=va%26lu%3d”,这样服务端会把紧跟在“%”后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分隔符。

另外一个问题,就是为什么我们要用ascii传输,可不可以用别的编码?

当然可以用别的编码,你自己可以开发一套编码,然后自己解析。就像大部分国家都有自己的语言一样。那国家之间要交流,怎么办?  用英语把,英语的使用范围最广。

通常如果一样东西需要编码,说明这样东西并不适合传输。原因多种多样,如size过大,包含隐私数据,对于url来说,之所以要进行编码,是因为url中有些字符会引起歧义。

例如,url参数字符串中使用key=value键值对这样的形式来传参,键值对之间以&符号分隔,如/s?q=abc&ie=utf-8。如果你的value字符串中包含了=或者&,那么势必会造成接收url的服务器解析错误,因此必须将引起歧义的&和=符号进行转义,也就是对其进行编码。

又如,url的编码格式采用的是ascii码,而不是unicode,这也就是说你不能在url中包含任何非ascii字符,例如中文。否则如果客户端浏览器和服务端浏览器支持的字符集不同的情况下,中文可能会造成问题。

url编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。

预备知识:uri是统一资源标识的意思,通常我们所说的url只是uri的一种。典型url的格式如下所示。下面提到的url编码,实际上应该指的是uri编码。

foo://example.com:8042/over/there?name=ferret#nose

\/ \/ \/\/ \/

|         |              |         |        |

scheme     authority                path      query   fragment

哪些字符需要编码

rfc3986文档规定,url中只允许包含英文字母(a-za-z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。rfc3986文档对url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。架构师必须掌握的各种编码:ascii、iso-8859-1、gb2312...,推荐阅读。

us-ascii字符集中没有对应的可打印字符:url中只允许使用可打印字符。us-ascii码中的10-7f字节全都表示控制字符,这些字符都不能直接出现在url中。同时,对于80-ff字节(iso-8859-1),由于已经超出了us-acii定义的字节范围,因此也不可以放在url中。

保留字符:url可以划分成若干个组件,协议、主机、路径等。有一些字符(