今天,刚刚学习PHP发现用echo输出中文时,页面会产出乱码,然后查了一晃材料说是浏览器编码格式有难点,要改成utf-8.不过各种人的浏览器编码可能会迥然分歧,所以找到了一个很好的化解方法,
浏览器能正确识其余编码格式,只要按照那样的编码来安装相应的Content-Disposition,那么应该就不会冒出中文文件名的乱码难题了。
第一,Content-Disposition值可以有以下两种编码格式
首先,说说JSP和Servlet中的多少个编码的成效。
用户从浏览器发起一个HTTP请求,存在编码的地方是URL、Cookie、Paramiter。服务器端接收到HTTP请求后要解析HTTP协议,其中URL、Cookie和POST表单参数要解码,服务器端可能还索要读取硬盘数据(数据库、文件),那一个数据都可能存在编码难题。当Servlet处理完所有请求的数量后,须要将那么些多少再编码通过Socket发送到用户请求的浏览器里,再经过浏览器解码成为文本。这个进程用图表示如下:
即便在php初步符号前边加上如此一句代码:
- 直接urlencode:
在JSP和Servlet中主要有以下几个地方能够安装编码,pageEncoding=”UTF-8″、contentType=”text/html;charset=UTF-
8″、request.setCharacterEncoding(“UTF-8”)和
response.setCharacterEncoding(“UTF-8”),其中前四个只好用来JSP中,而后三个可以用于JSP和Servlet中。
header('Content-Type:text/html;charset=utf-8');
如果你在刚刚学习php时遇到这种情况,又不想手动修改浏览器编码,那就试试加上这句代码吧.
Content-Disposition: attachment;
filename=”struts2.0%E4%B8%AD%E6%96%87%E6%95%99%E7%A8%8B.chm”
1、pageEncoding=”UTF-8″的功能是安装JSP编译成Servlet时选择的编码。
1.URL的编解码
为了表明浏览器是怎么编码URL的,我们选择FireFox浏览器并通过HTTPFox插件观望请求的URL的其实内容:
从结果上看,PathInfo是UTF-8编码,而QueryString是GBK编码。至于为啥有%,是由URL的编码规范FRC3986确定:浏览器编码URL将非ASCII字符根据某种编码格式编码成16进制数字后将各类16进制表示的字节前拉长“%”。
从地点的测试结果可以,浏览器对PathInfo和QueryString的编码是不均等的,不一致的浏览器对PathInfo的编码也恐怕差别。如Chrome会对请求“http://localhost:8080/中国?中国”转变为“Web中关系的编解码,不相同浏览器上中文文件名的上传。”,那里PathInfo和QueryString的编码是一模一样的,都是UTF-8编码。
- Base64编码:
不言而喻,JSP在服务器上是要先被编译成Servlet的。pageEncoding=”UTF-8″的效应就是报告JSP编译器在将JSP文件编译成Servlet时行使的编码。经常,在JSP内部定义的字符串(直接在JSP中定义,而不是从浏览器提交的数目)出现乱码时,很多都是由于该参数设置错误引起的。例如,你的JSP文件是以GBK为编码保留的,而在JSP中却指定pageEncoding=”UTF-8″,就会引起JSP内部定义的字符串为乱码。
2.HTTP Header的编解码
当客户端发起一个HTTP请求时,除了上边的URL外还可能会在Header中传送其他的参数,如Cookie、redirectPath等,那一个用户设置的值很可能也会存在编码难点。
在汤姆cat中,对Header中的项举行解码是在调用request.getHeader时举行的,假若请求的Header项没有解码则调用MessageBytes的toString方法,这些措施将从byte从char的倒车应用的默许编码是ISO-8859-1,而我们也无法设置Header的其它解码格式,所以如果你设置的Header中国和欧洲ASCII字符解码肯定会有乱码。
俺们在添加Header时也是同一的道理,不要在Header中传送非ASCII字符,如果一定要传递可以先将字符用org.apache.catalina.util.URLEncoder编码,然后再添加到Header中,那样在浏览器到服务器的传递中就不会丢掉新闻了,大家在造访那一个项时再依据相应的字符集解码就好了。
Content-Disposition: attachment;
filename=”=?UTF8?B?c3RydXRzMi4w5Lit5paH5pWZ56iLLmNobQ==?=”
除此以外,该参数还有一个功能,就是在JSP中不指定contentType参数,也不应用response.setCharacterEncoding方法时,指定对服务器响应进行重复编码的编码。
3.POST表单的编解码
POST表单参数传递方式与QueryString分裂,它是透过HTTP的BODY传递到服务端的。当我们在页面上点击提交按钮时浏览器首先将依照页面的ContentType的Charset编码格式对表单填的参数举行编码,然后交给到劳动器端。在劳务器端同样也是用ContentType中的字符集进行解码。所以经过POST表单提交的参数一般不会冒出难点,而且这么些字符集编码是大家团结安装的。
其余,针对multipart/form-data类型的参数,也就是上传的文本编码,同样也利用ContentType定义的字符集编码。值得注意的地点是,上传文件是用字节流的格局传输到服务器的地头临时目录,这些历程并从未关系字符编码,而实在编码是在将文件内容添加到parameters中时,假诺用这一个不可能编码将会用默许编码ISO-8859-1来编码。
- RFC2231确定的正规化:
2、contentType=”text/html;charset=UTF-8″的功能是指定对服务器响应举行重复编码的编码。
4.HTTP BODY的编解码
当用户请求的资源服务端已经成功得到后,这个情节将经过Response重返给客户端浏览器,那些历程先要经过编码再到浏览器进行解码,浏览器按照HTML的<meta
HTTP-equiv=“Content-Type” content=”text/html;
charset=GBK”>中的charset来解码。若是没有概念,那么浏览器将会利用默许的编码来解码。
走访数据库都是透过客户端JDBC驱动来形成的,用JDBC来存取数据要和数码的内置编码保持一致,可以通过安装JDBC
URL来指定。
Content-Disposition: attachment;
filename*=UTF-8”%E5%9B%9E%E6%89%A7.msg
在不行使response.setCharacterEncoding方法时,用该参数指定对服务器响应进行重复编码的编码。3、request.setCharacterEncoding(“UTF-8”)的效应是设置对客户端请求举办双重编码的编码。
5.JS中的编解码
html文件本身中的js的编码和脚下页面中的Content-Type保持一致。
对此利用<script
src=”script.js”/>类型引入的js文件,浏览器就会以当下这几个页面的默许字符集解析那几个JS文件,如若外部的JS文件的编码格式与当前页面的编码格式一致,那么可以不设置这一个charset。可是假诺script.js文件的编码格式与近来页面的不一样等,就必要求指定相应的字符集,要不然对于非ASCII字符就会冒出乱码。
- 直接ISO编码的文本名:
该办法用来指定对浏览器发送来的数码举行重复编码(或者叫做解码)时,使用的编码。
6.其余急需编码的地方
除开URL和参数编码问题外,在服务端还有为数不少地点恐怕存在编码,如可能须要读取XML、Velocity模板引擎、JSP或者从数据库读取数据等。
参考资料:《深刻剖析Java Web技术》
Content-Disposition: attachment;filename=”测试.txt”
4、response.setCharacterEncoding(“UTF-8”)的作用是点名对服务器响应进行重复编码的编码。
接下来,各浏览器援救的附和编码格式为:
服务器在将数据发送到浏览器前,对数据开展重新编码时,使用的就是该编码。
澳门葡京备用网址,1. IE浏览器,采用URLEncoder编码
2. Opera浏览器,采用filename*方式
3. Safari浏览器,选取ISO编码的中文输出
4. Chrome浏览器,选取Base64编码或ISO编码的汉语输出
5. FireFox浏览器,采用Base64或filename*或ISO编码的华语输出
说不上,要说一说浏览器是怎么对收取和殡葬的数码进行编码的
new_filename = URLEncoder.encode(filename, “UTF8”);
// 如若没有UA,则默许使用IE的点子举办编码,因为毕竟IE照旧占多数的
rtn = “filename=\”” + new_filename + “\””;
if (userAgent != null)
{
userAgent = userAgent.toLowerCase();
// IE浏览器,只好采取URLEncoder编码
if (userAgent.indexOf(“msie”) != -1)
{
rtn = “filename=\”” + new_filename + “\””;
}
// Opera浏览器只可以选择filename*
else if (userAgent.indexOf(“opera”) != -1)
{
rtn = “filename*=UTF-8”” + new_filename;
}
// Safari浏览器,只好利用ISO编码的汉语输出
else if (userAgent.indexOf(“safari”) != -1 )
{
rtn = “filename=\”” + new
String(filename.getBytes(“UTF-8″),”ISO8859-1”) + “\””;
}
// Chrome浏览器,只可以采用MimeUtility编码或ISO编码的国语输出
else if (userAgent.indexOf(“applewebkit”) != -1 )
{
new_filename = MimeUtility.encodeText(filename, “UTF8”,
“B”);
rtn = “filename=\”” + new_filename + “\””;
}
//
FireFox浏览器,可以应用MimeUtility或filename*或ISO编码的国语输出
else if (userAgent.indexOf(“mozilla”) != -1)
{
rtn = “filename*=UTF-8”” + new_filename;
}
}
response.setCharacterEncoding(“UTF-8”)的职能是点名对服务器响应进行再度编码的编码。同时,浏览器也是依照这么些参数来对其吸收到的多少开展双重编码(或者叫做解码)。所以在无论你在JSP中装置response.setCharacterEncoding(“UTF-8”)或者
response.setCharacterEncoding(“GBK”),浏览器均能正确展现普通话(前提是您发送到浏览器的数据编码是不错的,比如正确安装了pageEncoding参数等)。读者可以做个实验,在JSP中装置response.setCharacterEncoding(“UTF-8″),在IE中显得该页面时,在IE的菜单中接纳”查看(V)”à”编码(D)”中可以查阅到是”
Unicode(UTF-8)”,而在在JSP中装置response.setCharacterEncoding(“GBK”),在IE中显示该页面时,在IE的菜单中选取”查看(V)”à”编码(D)”中可以查阅到是”简体汉语(GB2312)”。
此时此刻,我测试的动静,在多少个浏览器上都能健康输入中文文件名
但,也许浏览器分歧版本,可能还会有乱码的意况…..
作者:xrzs
浏览器在发送数据时,对URL和参数会举行URL编码,对参数中的中文,浏览器也是使
response.setCharacterEncoding参数来开展URL编码的。以百度和GOOGLE为例,假设您在百度中摸索”汉字”,百度会将其编码为”%BA%BA%D7%D6″。而在GOOGLE中搜索”汉字”,GOOGLE会将其编码为”%E6%B1%89%E5%AD%97″,那是因为百度的response.setCharacterEncoding参数为GBK,而GOOGLE的的
response.setCharacterEncoding参数为UTF-8。
首先,…
浏览器在吸收服务器数据和发送数据到服务器时所接纳的编码是同一的,默许意况下均为JSP页面的response.setCharacterEncoding参数(或者contentType和pageEncoding参数),大家称其为浏览器编码。当然,在IE中得以修改浏览器编码(在IE的菜单中选取”查看(V)”à”编码(D)”中修改),但一般状态下,修改该参数会使本来不错的页面中冒出乱码。一个有意思的事例是,在IE中浏览GOOGLE的主页时,将浏览器编码修改为”简体粤语(GB2312)”,此时,页面上的汉语会变成乱码,不理它,在文本框中输入”汉字”,提交,GOOGLE会将其编码为”%BA%BA%D7%D6″,可知,浏览器在对粤语举行URL编码时,使用的就是浏览器编码。
弄清了浏览器是在收取和发送数据时,是怎么对数码举办编码的了,大家再来看看服务器是在接受和发送数据时,是何等对数码举行编码的。
对此发送数据,服务器按照response.setCharacterEncoding—contentType—pageEncoding的优先顺序,对要发送的数目开展编码。
对于接收数据,要分三种状态。一种是浏览器直接用URL提交的数据,其余三种是用表单的GET和POST方式提交的数量。
因为各样WEB服务器对那三种艺术的处理也差异,所以我们以Tomcat5.0为例。
任凭使用这种格局交给,如果参数中包含中文,浏览器都会利用当前浏览器编码对其进展URL编码。
对于表单中POST方式提交的多寡,只要在接收数据的JSP中科学request.setCharacterEncoding参数,即将对客户端请求举行重复编码的编码设置成浏览器编码,就足以确保收获的参数编码正确。有写读者也许会问,那什么赢得浏览器编码呢?下面大家提过了,在默认请情状下,浏览器编码就是你在响应该请求的JSP页面中response.setCharacterEncoding设置的值。所以对于POST表单提交的数据,在得到数据的JSP页面中request.setCharacterEncoding要和浮动提交该表单的JSP页面的response.setCharacterEncoding设置成相同的值。
对此URL提交的数目和表单中GET格局提交的数码,在接收数据的JSP中装置request.setCharacterEncoding参数是充足的,因为在汤姆cat5.0中,默许处境下使用ISO-8859-1对URL
提交的多寡和表单中GET格局交给的多寡举办重复编码(解码),而不行使该参数对URL提交的数量和表单中GET格局交给的数目举行再度编码(解码)。要化解该难题,应该在汤姆cat的布局文件的Connector标签中设置useBodyEncodingForURI或者URIEncoding属性,其中useBodyEncodingForURI参数表示是或不是用request.setCharacterEncoding参数对URL提交的多少和表单中GET方式提交的多寡进行重新编码,在默许情状下,该参数为false(汤姆cat4.0中该参数默许为true);URIEncoding参数指定对所有GET形式呼吁(包涵URL提交的数码和表单中GET情势提交的数码)进行合并的双重编码(解码)的编码。URIEncoding和
useBodyEncodingForURI差别是,URIEncoding是对具备GET方式的央浼的多寡开展联合的重新编码(解码),而
useBodyEncodingForURI则是按照响应该请求的页面的request.setCharacterEncoding参数对数据举行的双重编码(解码),差其他页面可以有区其他再一次编码(解码)的编码。所以对于URL提交的多少和表单中GET格局交给的多少,可以修改URIEncoding
参数为浏览器编码或者修改useBodyEncodingForURI为true,并且在得到多少的JSP页面中request.setCharacterEncoding参数设置成浏览器编码。
下边计算下,以Tomcat5.0为WEB服务器时,如何预防中文乱码。
1、对于同一个利用,最好统一编码,推荐为UTF-8,当然GBK也得以。
2、正确安装JSP的pageEncoding参数
3、在颇具的JSP和Servlet中安装contentType=”text/html;charset=UTF-8″或response.setCharacterEncoding(“UTF-8”),从而直接完结对浏览器编码的设置。
4、对于请求,可以利用过滤器或者在每个JSP和Servlet中装置request.setCharacterEncoding(“UTF-8”)。同时,要修改汤姆cat的默许配置,推荐将
useBodyEncodingForURI参数设置为true,也可以将URIEncoding参数设置为UTF-8(有可能影响其余应用,所以不引进)。