http请求,编码、解码、JSP页面乱码问题梳理

以下内容是基于java开发来作说明的...........

如果你只是想解决问题,请你按照以下两点加上配置即可:

1.JSP页面乱码,你就加上<%@ page language="java" contentType="text/html; charset=UTF-8"  %>

2.后端接收到的汉字乱码,如果你用的是tomcat服务器,在conf/server.xml中配置如下两点中的一点就可以:

<Connector>中 添加uriEncoding="UTF-8"   

<Connector>中 添加useBodyEncodingForURI="true"  

如果你想了解发送请求->接受请求->返回响应->渲染页面这个过程消息内容到底是如何编码解码的你就接着往下看

网上查了不少关于http请求编码解码的文章,看完感觉都没完全理清楚,没办法只能自己验证:

我们首先说下http消息头中content-type属性:Content-Type:text/html;charset=UTF-8,注意下面我们只针对charset这个属性来做说明:
无论是请求还是响应,这都代表了一种编码解码字符集协商,客户端与服务端告诉对方我是用的这个字符集对消息体进行编码的(注意这里是消息体),你也用这个来解码吧,于是接受的一方就会通过协商的这个字符集进行解码(我们下面说到的 字符集协商就代表消息头中的这个属性)

服务端响应客户端时指定编码方式有如下两个:
response.setContentType("text/plain; charset=utf-8")  
response.setCharacterEncoding("charset=utf-8");
两种方式都可以设置响应时,服务端对响应内容的编码方式
并且前者还会同时设置响应消息头中的content-type类型,进行字符集协商

JSP文件中的编码解码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
我们看到这里涉及到两个编码:
1.其中pageEncoding="UTF-8"这个好理解,无论什么文件自身都会有一个编码方式,而这个就指定了jsp文件本身内容的编码方式,这个与请求交互中的编解码没有关系
2.contentType="charset=UTF-8"  这个属性有三个作用:
a.针对页面本身:替代上面说的pageEncoding指定页面自身编码(所以如果指定了这个参数,pageEncoding去掉也没有关系,待会我会用我试验的截图给大家解释)
b.针对服务端返回页面响应内容:表示服务端返回我这个页面时对响应内容的编码方式,以及响应消息头中的 字符集协商
c.针对客户端页面提交的请求内容:指定页面提交请求时对请求内容的编码方式(不包括ajax请求啊),以及请求消息头中的 字符集协商
我们都知道,jsp文件都会被编译为servlet的class文件来执行,我们看到的浏览器页面内容(静态的以及动态的)都是在servlet中生成并输出到浏览器页面的,在Tomcat中生成的java及class文件在tomcat\work目录下,我用我本地的一个jsp做了如下试验:

当我修改JSP文件的charset=iso-8859-1后,  

tomcat对应生成的java文件如下: 


图片上我标了两个重点:

扫描二维码关注公众号,回复: 1512361 查看本文章

    第一个是servlet设置了响应时的字符集协商,代表了servlet会用这个字符集对接下来要输出给页面的内容进行编码,并且告诉客户端你就用我这个字符集对内容进行解码。这个验证了上面说的jsp页面指定的b作用,

    第二个是jsp里自带的中文字被编码成这个样子,这验证了我上面说的charset可以替代pageEncoding来指定页面自身的编码。

当我改成charset=utf-8后,上面标的两点都对应改动了。

上面说了服务端对客户端的响应编解码,下面我们再看客户端请求服务端,分为以下几种情况:

1.页面的get请求(包含浏览器地址栏输入url直接请求)
2.页面form表单的 post请求
3.ajax的get post请求
我们分别说明上述几种情况客户端是如何对请求内容进行编码,服务端又是如何对请求内容进行解码的
首先:对于前两种情况,客户端都会按照页面中设置的contentType中指定的字符集对请求内容进行编码,并且会设置请求消息头中的content-type类型,上面说了,这就相当于告诉服务端你就用这个来对我的消息中的消息体进行解码就好了
对于post请求由于请求参数都在消息体中,所以服务端解码得出的参数肯定不会乱码
而对于get请求,请求参数都在Url中,而服务端对url和消息体解码的方式是不一致的,
所以服务端需要 指定对Url的解码方式以防止用默认方式解码,tomcat服务器中指定Url解码方式的配置有如下两种:
1)在server.xml的<Connector>中 添加 uriEncoding="UTF-8"   这个很好理解
2)在server.xml的<Connector>中 添加 useBodyEncodingForURI="true"  这个意思就是服务端收到的http请求头中指定的消息体编码方式是什么,就用这个编码来对uri进行解码
其次:对于ajax请求,编码方式与页面指定的charset就无关了,需要另行指定,使用jquery来发送ajax请求时,jquery已经指定了编码的方式为UTF-8,并且设置了消息体编码协商。

猜你喜欢

转载自blog.csdn.net/wb_snail/article/details/79926058