说说http协议中的编码和解码
********************************************************************************
⼀、字符集与⽂字编码简介 
  1. 计算机如何显⽰⽂字
  我们知道,计算机是以⼆进制的“形式”来保存和处理数据的,也就是说,不管我们使⽤键盘进⾏输⼊,还是让计算机去读取⼀个⽂本⽂件,计算机得到的原始内容是⼀些⼆进制序列,当需要对这些⼆进制序列进⾏显⽰时,计算机会依照某种“翻译机制”(也就是编码⽅式),取到这些⼆进制序列所表⽰的每个⽂字的“轮廓描述”(点阵或者⽮量图),知道了轮廓,计算机便可以将⼆进制序列所表⽰的实际的⽂字形状显⽰到屏幕上了,这⾥⾯的思想和⽤学号来表⽰⼀个学⽣是⼀样的。(当然,这⾥⾯具体的知识点会很多,相关知识可以参考《计算机图形学》中显⽰原理的部分和其他与计算机显⽰原理相关的基础书籍)。
2. 字符集
  将⼀些⾃然语⾔中的字符组成⼀个集合,并对集合中的每个字符制定规范化的编码⽅式,这个字符的集合和规范化的编码⽅式就组成了⼀个字符集。如ASCII字符集⾥⾯包括了所有的英⽂字母,并且指定了这
些英⽂字母的编码规则。GB2312字符集⾥⾯包括了常⽤的简体汉字,并且指定了这些简体汉字的编码规则。
3. 字符编码
  字符编码,就是建⽴⼀套⾃然语⾔中的“字符”跟计算机能够存储处理的⼆进制数的映射的规则,即在⼀个字符集内,⽤⼀个特定的⼆进制数表⽰⼀个唯⼀“字符”,类似于学号跟学⽣的映射关系。为了保证统⼀性,兼容性,国际上会对“字符”和“内码”的映射关系指定标准,这样就有了ASCII、Unicode等标准的编码⽅式,详细的编码⽅式请参考字符编码和其他相关资料。
⼆、泛意义上的编码和解码
1. 为什么需要编码
  当数据不利于处理、存储的时候,就需要对它们进⾏编码。如对字符进⾏编码是因为⾃然语⾔中的字符不利于计算机处理和存储。
对图⽚信息、视频信息、声⾳信息进⾏压缩、优化,将其“格式化”,是为了在保证媒体资源质量的同时,尽量的节省⽹络带宽和本地存储的空间。对URL进⾏编码,是为了避免URL解析发⽣歧义,简化解码⽅式,如:URL采⽤“&”作为不同参数的分隔符,假如某个特定的参数的名称或者值本⾝就包括分
隔符“&”,如果不将参数中的“&”做编码转换,那势必会增加URL解析的复杂性,提⾼解析错误的概率。
2. 怎么样进⾏编码和解码
  根据实际需求的差异,编码、解码算法有可能会很复杂,也有可能⾮常的简单,但是从根本上来讲,编码、解码只是在做翻译⼯作,将⼀种形式的数据翻译为另⼀种形式的数据,如,最简单的编码、解码就是相当于从⼀个Map中根据key查value,然后使⽤value代替实际数据中的key的值。复杂⼀点⼉的编码如javascript中
的encodeURIComponent和decodeURIComponent,encodeURIComponent负责将字符串中不符合URL编码规范的字符转换为“%”形式的⼗六进制Unicode内码序列,decodeURIComponent负责将“%”形式的⼗六进制Unicode内码序列转换为实际的字符。
三、HTTP协议中的编码和解码
1. URL的编码和解码
  ⾸先,由于URL是采⽤ASCII字符集进⾏编码的,所以如果URL中含有⾮ASCII字符集中的字符,那就需要对其进⾏编码。再者,由于URL中好多字符是保留字,他们在URL中具有特殊的含义。如“&”表⽰参数分隔符,如果想要在URL中使⽤这些保留字,那就得对他们进⾏编码。
  根据2005年发布的RFC3986“%编码”规范:对URL中属于ASCII字符集的⾮保留字不做编码;对URL中的保留字需要取其ASCII 内码,然后加上“%”前缀将该字符进⾏替换(编码);对于URL中的⾮ASCII字符需要取其Unicode内码,然后加上“%”前缀将该字符进⾏替换(编码)。由于这种编码是采⽤“%”加上字符内码的⽅式,所以,有些地⽅也称其为“百分号编码”。
  虽然“百分号编码”对URL的编码⽅式做了详细的规定,但是实践中,浏览器对于URL的编码⽅式还是存在⼀些差异(主要表现在对⾮ASCII字符编码的差异),接下来我们⾸先展⽰不同浏览器(chrome和IE)对URL编码
的差异性,然后再对这些差异性做⼀些客观的总结和分析。
a) chrome
b) IE
可以看出对于路径中的⾮ASCII字符,chrome和IE都是按照RFC3986“%编码”进⾏编码的,取的是⾮ASCII字符的Unicode内码。
  a) chrome和IE11
  b) IE11以下版本(使⽤gbk进⾏解码)
可以看出对于查询参数中的⾮ASCII字符,chrome及其IE11都是按照都是按照RFC3986“%编码”进⾏编码的,取的是⾮ASCII字符的Unicode内码。IE11以下版本直接发送的是⾮ASCII字符相对应的当前系统默认编码的内码。
  a) Chrome
    i. 页⾯gbk编码
    ii. 页⾯utf-8编码
  b) IE
    i. 页⾯gbk编码
    ii. 页⾯utf-8编码
可以看出当通过表单发送get请求时,对于表单字段内容中的⾮ASCII,chrome和IE都会采⽤当前页⾯的编码对其进⾏“百分号”编码。
  a) chrome
    i. 页⾯UTF-8编码
    ii. 页⾯GBK编码
在线url网址编码解码
  b) IE
    i. 页⾯UTF-8编码
    ii. 页⾯GBK编码
可以看出当通过表单发送post请求时,对于表单字段内容中的⾮ASCII,chrome和IE都会采⽤当前页⾯的编码对其进⾏“百分号”编码。
  a) Chrome
    i. 页⾯utf-8编码
    ii. 页⾯gbk编码
  b) IE
    i. 页⾯utf-8编码
      1. IE6(gbk解码)
      2. IE11
    ii. 页⾯GBK编码
      1. IE6(gbk解码)
      2. IE11
可以看出,对于URL中的⾮ASCII字符,ie6没有做任何的编码⼯作,⽽chrome和IE11则是按照⽤表单get请求的⽅式对URL进⾏编码的。
  a) Chrome
    i. 页⾯utf-8编码
    ii. 页⾯gbk编码
  b) IE
    i. 页⾯utf-8编码
      1. IE6
      2. IE11
    ii. 页⾯GBK编码
      1. IE6
      2. IE11
可以看出,对于使⽤post发送并且content-type为application/x-www-form-urlencoded的请求,各个浏览器都没有对数据进⾏“百分号”编码。
从上⾯的实验结果我们看得出:
① 对于URL中的路径部分,IE和chrome都会统⼀采⽤utf-8编码对URL中的⾮ASCII字符进⾏百分号编码。
② 对于新开页⾯,IE11以下版本不会对URL中的参数部分做编码,chrome和IE11会采⽤utf-8编码对
URL中的⾮ASCII字符进
⾏百分号编码。
③ 对于通过表单发起的请求(不管是post还是get⽅式),IE和chrome都会采⽤当前页⾯的默认编码对URL参数中的
⾮ASCII字符进⾏百分号编码。
④ 对于AJAX通过get⽅式发起的请求,IE11和chrome会根据当前页⾯的默认编码对URL参数中的⾮ASCII字符进⾏百分号编
码。⽽IE6不会对URL⾮ASCII表⽰的路径信息和参数信息进⾏编码。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。