B/S交互中为何出现乱码个人浅析

来源:互联网 发布:网络群发软件通科 编辑:程序博客网 时间:2024/06/05 07:21

前言:要理解这些你需要知道字符编码的本质,压缩和解压缩的本质等

首先,客户端在请求数据的时候并不知道服务器会以什么编码返回数据,所以请求头部会含有Accept-Encoding,Accept-Charset,Accept-language等信息,这个的目的就是告诉服务器自己可以接受的各种编码和MIME类型等,但是我用代理工具拦截请求数据时发现,请求头中很少有Accept-charset这个信息,也就是说,客户端并没有指定自己可以接受的编码类型,或者说客户端可以接受任何的编码类型,这就导致服务器总是按照自己设定的或者被开发者指定的编码方式发送数据给客户端,这其实才是乱码的本质。

再来详细解释一下我对乱码的理解,刚已经说过,客户端很少指定自己可接受的编码方式,因为现在的操作系统,客户端或者说是浏览器几乎可以解析任何的编码格式,因此没有必要指定编码(题外话,如果指定的话,一个请求就需要增加几十个字符所占用的字节,整个互联网一秒钟所发送的请求量之大我们难以想象,这几十个字节再乘以请求量可以想象为整个网络所带来的网络负载有多大,经济损失又得多大。。。)。现在客户端请求发送到了服务器,首先监测服务器被请求页面有没有指定编码格式,没有则是按照默认的方式,如果既没有指定,而且服务器页面又有中文,那么服务器回送给客户端的数据是按照默认的ISO-8859-1进行编码的,同时会告诉客户端用这个编码进行解码,此时乱码自然就出现了,此时我们需要想到为什么B/S用的同样的编码方式,为什么服务器看起来是正常,而客户端乱码呢?这是因为服务器端有自己的数据编码方式,假设“程序员”这三个字,服务器显示的时候用的是utf-8,utf-8的二进制是1010110   0011101  110101(不要在意错对,重在原理)  ,而服务器回送数据的时候按照默认的ISO-8859-1进行发送,假设这种编码一个字符用5个二进制位,那么此时原来的编码就成了10101  10001   11011   10101,三个字变成了五个字,不乱码才怪,(要理解这个需要再加一点东西:不管什么编码,不同的客户端在显示同一个数据的时候用的是同一个数据实体,而不同的客户端则用的不同的编码算法进行字符编码,那么同一个数据实体所解析出来的数据自然不一样。同样,服务器显示数据的时候用的编码,与服务器发送数据的时候用的编码也是互不影响的,但是他们用的是同一个数据实体)。

请求通过Servlet的时候出现乱码,这又是为什么呢?同样的道理,在Servlet变成中,在解析请求数据之前经常可以看到request.setCharacterEncoding("UTF-8");这个就是告诉接下来的程序代码,客户端请求的数据是以utf-8的编码方式编码的,然后服务器中的Servlet或者JSP或者其他解析器就会按照指定的编码方式进行解码,那么就不会出现乱码了。

request.getParameter("name")).getBytes("ISO-8859-1"),"UTF-8");
这段代码应该见过,这个的本质其实就是String.getBytes("A","B");将A编码的数据转换成utf-8的编码方式,这是因为request.getParameter("name"))是以ISO-8859-1编码方式得到数据,然后getBytes("ISO-8859-1"),"UTF-8")再将这个编码的二进制进行底层的转换变成utf-8的编码方式,这可能使得数据发生变化,因为不同的编码方式占用的字节数不一样。


《个人暂时理解,可能有错,仅供参考》

0 0
原创粉丝点击