Http请求和响应的编码问题
前⾔:
今天来谈谈Tomcat服务器和⽹页之间编码和解码之间的关系。
关于URL编码的问题可以看
修正:百度现在编码也是UTF-8
关于编码之间的转换问题可以看
浏览器端的编码:
默认解码是GB2312
影响form提交数据的编码的因素包括:form的accept-charset属性、html⽂档的编码⽅案即document.charset。其中,form的
accept-charset是否能够有效,依赖具体浏览器的实现,有些浏览器并不⽀持,如IE。⽂档编码⽅案可以通过document.charset来修改。浏览器端的解码:
默认解码是GB2312
这个是国情所致,不管是windows还是linux都是如此,除⾮⾃⼰设置。
通常来说,浏览器会先按照Content-Type的编码设置来解析⽂本,然后在解析过程中发现charset设置,再更换编码重新读取。若Content-Type没有设置编码,或者说这个HTML⽂件根本就不是⾛的HTTP协议,浏览器通常会猜测编码来解析⽂本,然后发现charset设置再更换编码读取。
来做个测试:
写了⼀个⽹页 没有声明meta等编码格式,但是⽂本是UTF-8编写的。
这时候浏览器打开该⽹页,发现乱码问题。
然后后台接受数据
request.setCharacterEncoding("GBK"); //或者GB2312
System.out.Parameter("name"));
输出结果不是乱码。
替换:
request.setCharacterEncoding("UTF-8"); //或者不写
System.out.Parameter("name"));
就根据request默认编码格式 iso-8859-1出现乱码。
浏览器的数据体解码⽅案依赖返回信息。
a) 浏览器⾸先从返回头header中查编码⽅案标注(Content-Type),举个栗⼦:
response.setHeader
("content-type", "text/html;charset=utf-8");
b)如果没有标注,在得知返回内容为html内容的话,将从head的meta标签中读取,举个栗⼦:
<meta http-equiv=Content-Type
content="text/html;charset=utf-8">
c)如果还没到,浏览器就不知道如何解码,会消极的选择⼀种解码⽅案。默认解码是GB2312
在理论上,推荐html⽂档在meta中声明编码,且编码的声明⼀定要在⽂件开始的1024字节内完成,所以最好在head标签开始时⽴即声明。
总结:服务器的编码解码主要是看:
1. 头header中meta的编码⽅案
2. html⽂档的编码⽅案
3. form的accept-charset编码⽅案
只要页⾯声明了charset什么格式,那么编码和解码就什么格式。
服务器端的编码:
中⽂版的浏览器⼀般会默认的使⽤GBK,通过设置浏览器也可以使⽤UTF-8,可能不同的⽤户就有不同的浏览器设置,也就造成不同的编码⽅式,所以很多⽹站的做法都是先把url⾥⾯的中⽂或特殊字符⽤ javascript做URL encode,然后再拼接url提交数据
Tomcat8以上默认是UTF-8
所以编码默认是UTF-8
所以getBytes()是默认采⽤UTF-8 还可以选择编码格式。
举个栗⼦:
("22这d是⼀个字节输出".getBytes("GBK"));
分析:
response存放的格式是GBK 浏览器默认是GBK打开正常显⽰
如果改为.getBytes()则为UTF-8浏览器打开就会乱码
总结:
HttpServletResponse跟HttpServletRequest默认编码不⼀样
HttpServletResponse默认编码不是iso-8859-1,⽽是取决于直接存⼊的编码格式,意思取决于getBytes。
默认应该是在doGet⽅法中,因为浏览器默认是以Get⽅式访问Servlet。
设置浏览器解码格式
response.setHeader("Content-type", "text/html;
charset=UTF-8");
如果修改的话 可以看这⼀篇 很详细:在线url网址编码解码
修正:
默认编码格式是UTF-8
完整栗⼦:
response.setHeader("Content-type", "text/html;charset=UTF-8");
输出:
22这是⼀个字节输出
总结:
1. getOutputStream和getWriter这两个⽅法互相排斥,调⽤了其中的任何⼀个⽅法后,就不能再调⽤另⼀⽅法。
2. getOutputStream()和getWriter()可以层叠使⽤。
3. Serlvet的service⽅法结束后,Servlet引擎将检查getWriter或getOutputStream⽅法返回的输出流对象是否已经调⽤过close⽅法,如果没有,Servlet引擎将调⽤close⽅法关闭该输出流对象。
服务器端的解码:
这块是我认为最难理解的。……
可以参考这篇:
1. Tomcat8以上版本默认编码格式是UTF-8
2. HttpServletRequest和HttpServletResponse容器默认编码格式是iso-8859-1
Get和Post解码格式:
request容器保存的是浏览器的数据,⼀般是UTF-8格式。
request的⽅法如:getParameter解码格式会根据Get和Post来设置解码格式。
1.Get默认解码格式是Tomcat8编码格式。所以URL解码是UTF-8,
覆盖掉了request容器解码格式
2. Post默认解码格式是request编码格式。与Tomcat8编码格式⽆关
从浏览器发起的访问⽅式有三种:
request乱码指的是:浏览器向服务器发送的请求参数中包含中⽂字符,
服务器获取到的请求参数的值是乱码;
⼀般默认浏览器传递过来的数据是UTF-8格式。
对于传输的数据 有两种⽅式传输 ⼀种是Post⼀种是Get 对于不同⽅式传递过来的数据。解码⽅式⼜是不同的。
Get是放在URL参数
Post是放在实体内容⾥
但都可以通过HttpServletRequest request来解码
在地址栏直接输⼊URL访问、
点击页⾯中的超链接访问、
提交表单访问。
第⼀种访问⽅式浏览器默认将参数按照utf-8进⾏编码,
后⾯两种访问⽅式浏览器将参数按照当前页⾯的显⽰编码进⾏编码。所以对于request乱码,只需要在服务器端设置相应的解码格式即可。由于访问⽅式不同,浏览器对参数的编码格式也不同,为了⽅便处理,通过超链接和表单的访问也规定必须是utf-8格式,即显⽰当前页⾯的编码也要使⽤utf-8,这样浏览器将统⼀使⽤utf-8对参数进⾏编码。
在服务器端,通过request.setCharacterEncoding(“utf-8”)即可设置服务器response容器的编码为utf-8(默认是ISO-8859-1), 但是它只对请求体⾥⾯的参数有效;
如果参数跟在请求⾏中的uri后边,它就⽆能为⼒了。因此请求⽅式不同,解决乱码的⽅案也不同。
通过修改l指定服务器对get和post统⼀按照utf-8解码,要求tomcat管理下的所有web应⽤都要使⽤utf-8编码
结论: 约定很重要,⽹站⼀般采⽤UTF-8作为默认编码。如果不是特殊需求,不要变换成其他编码。
总结:get请求建议尽量不带中⽂参数
“`
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论