zoukankan      html  css  js  c++  java
  • IE6 发送奇数个汉字出现的BUG机器解决之道

      一 IE6与IE7向服务器传递参数的问题

        表现:ie7正常,ie6 参数就会出现中文接受信息错误(长度为奇数时最后一个字符会出现乱码)

        原因:ie7支持UTF8编码,但是ie6支持不好。

        解决方法:

        1、用post发送,这个方法当然不出错了,但是,有时候必须用传参的方法,那就没则了,用第二个方法。

        2、习惯把中文字符串显示长度设置为偶数 ——全是汉字时,无论奇数还是偶数,都无乱码;
    如果是英文中文混合,并且英文字符数是奇数时,就会出现最后有一个?号;
    如果是英文中文混合,并且英文字符数是偶数时,无乱码。

        解决方案:在业务方法里进行判断,如果输入的字符个数为奇数,则给其拼接上一个全角的空格,如果是半角的空格,也会有乱码问题;或者,在js里面利用escape()函数来解决:

        <script>

            url = "object.html?name=" + escape("张三丰");

        </script>

        原理:见下文——在windows操作系统上使用IE作为浏览器时,常常会发生这样的问题:在浏览使用UTF-8编码的网页时,浏览器无法自动侦测(即没有设定“自动选择”编码格式时)该页面所用的编码,即——当网页标题是中文时,可能会出现打不开网页的情况;即使网页已经声明过编码格式:<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />也会造成某些含有中文UTF-8编码的页面产生空白输出。

        如果使用的是Mozilla、Mozilla Firefox、Sarafi的浏览器这不会造成这个问题。这是由于IE解析网页编码时以HTML内的标签优先,而后才是HTTP header内的讯息;而mozilla系列的浏览器则刚刚相反。

        由于UTF-8为3个字节表示一个汉子,而普通的GB2312或BIG5是两个,因此,页面输出时,由于上述原因,使浏览器解析、输出<title></title>的内容时,如果在</title>前有奇数个全角字符时,IE把UTF-8当作两个字节解析时出现半个汉字的情况,这时该半个汉字会和</title>的<结合成一个乱码字,导致IE无法读完<title>部分,使整个页面为空百输出。而这个时候如果察看源文件的话,会发现实际上整个叶面全部已经输出了。

        因此最简单的解决办法是再网页文件的<head></head>标签中一定要把字符定义<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 放在<title></title>之前。

        下面再通过一篇文章来全面说明一下web开发中的编码转换过程及其解决之道:

        

    一个请求响应的流程:

    浏览器 IE/FireFox ----------->Servlet容器------------------------>显示页面

           编码                           使用容器的URIEncoding转码              解码

    我把用户发送请求方式不同引起的中文问题划分了四种类型:

    1、表单的get提交

    2、表单的post提交

    3、页面链接传递中文参数

    4、地址栏中参数直接输入中文提交

     

    1.首先我们看表单get方式提交

          浏览器根据页面的charset编码方式对页面进行编码,然后提交至服务器,首先进入对应的字符编码过滤器(如果有的话),不过Tomcat6.0对于 get提交方式采用的是server.xml文件中的URIEncoding编码方式,而并不会采用过滤器中设置的编码,那么根据我的环境设置,jsp页面都使用UTF-8的编码,Servlet容器的URIEncoding也设置为UTF-8,则servlet不用进行转码即可正确解码,获得正常的中文字符串。那么,响应页面的中文因为页面的统一编码(UTF-8)自然也会正常显示。当然,如果我们Tomcat的URIEncoding设置为其他非 UTF-8的编码方式时,页面的内容进入Tomcat解析时,因为Tomcat和页面的编码不统一,就需要转码。例如,如果我们采用Tomcat默认的 ISO-8859-1,那么当我们使用request.getParameter("yourVariable ")获取表单参数值时其实Servlet就进行了转码,方式为UTF-8-->ISO-58859-1(我的页面charset都是UTF-8),类似于这样

    Java代码
    1. new String(变量值.getBytes("UTF-8"),"ISO-8859-1");  

    new String(变量值.getBytes("UTF-8"),"ISO-8859-1");

     例如表单的username属性以字符串"编辑"提交,那么进入容器后,FormBean中的这个变量会乱码,request.getParameter(username)一样的效果,s1就是request返回的结果,下面是内存快照。

    不过即使这样,我们依然可以使用不恰当的方法显示正常的中文,即逆向转码,例如上面的乱码,我们可以通过ISO8859-1-->UTF-8这种方式还原我们提交时的中文。以下是GBK,UTF-8,ISO-8859-1三者之间互相转换的内存快照:

     我们可以看到,偶数汉字可以在UTF-8,GBK两者中互相转换,而奇数个汉字则不能。综上看来,貌似Tomcat的URIEncoding设置为UTF-8是最好的解决办法,不过这样的设置依然无法解决上面我所说的第三、第四种情况。大家继续向下看。(这里有一点我不确定,就是页面提交至 Servlet容器时,是以页面的charset方式编码后直接进入容器,还是以charset转码为ISO-8859-1方式进入,大家有什么见解?)
    2.表单的post提交

    对于这种方式的请求,request.setCharacterEncoding("一般来自于web.xml中过滤器设置的参数")方法进行编码设置将会产生作用,struts的表单提交方式默认为post方式,那么按照上面我的环境设置,页面,容器,都采用UTF-8编码方式,就不会产生中文乱码问题。
    3.页面链接中传递中文参数

    我虚拟一个这样的场景,请求页面中有如下代码

    Html代码
    1. <%  
    2. String username = "编辑";  
    3. %>  
    4. <a href="hello.do?username=<%=username%>">页面中链接传递中文</a>  

    <% String username = "编辑";%> <a href="hello.do?username=<%=username%>">页面中链接传递中文</a>

    对于这种方式,我们需要先将参数使用统一的编码方式编码,将编码后的字符放入链接,这里我对参数以UTF-8方式编码,如下

    Java代码
    1. <%  
    2. String username = java.net.URLEncoder.encode("编辑","UTF-8");  
    3. %>  

    <% String username = java.net.URLEncoder.encode("编辑","UTF-8");%>

    那么这样我们也不会产生中文乱码问题

    4.地址栏中参数直接输入中文提交

    例如浏览器地址栏中输入"http://localhost:8080/helloapp.do?username=编辑"提交,对于这种方式,浏览器不会采用页面的charset方式对URL中的中文进行编码后提交至服务器(IE,FireFox都一样),而是采用系统的GBK转码为ISO- 8859-1之后提交至Servlet容器,那么,如果对于前三种方式我们所做的设置,在这里就有问题了,因为进入容器时中文进行了GBK至ISO- 8859-1的转码,而之前我们的Servlet容器URIEncoding设置为UTF-8,当我们使用 request.getParameter("username")时,相当于又进行了这样的流程GBK-->ISO- 8859-1-->UTF-8,按照以上我们使用的测试中文,“编辑”,使用request.getParameter("username")则会得到这样的结果�༭,下图是进行转码的内存快照:


    我们可以看到

    “编辑”经过从GBK-->ISO-8859-1-->UTF-8的过程后得到的就是�༭这样的结果,这里我们还会想到那进行2次逆向转码看看,不过可惜的是,结果为“锟洁辑”。对于这种情况,我们的解决办法就是,Tomcat的URIEncoding采用默认的ISO-8859-1字符集,那么我们可以在程序中通过ISO-8859-1-->GBK这样不恰当的逆向转码方式得到正常的中文“编辑”,但这样的结果是,我们get请求方式的中文处理解决办法就需要改变。如,在我的环境下就需要进行ISO-8859-1-->UTF-8的转码,挺不爽。

     

    综上,对于乱码问题,前三种方式是一般用户的请求方式,第四种属于非正常途径的请求方式,对于这种方式产生的问题我认为无法很好的解决,也不需要解决。我看到javaeye对于这样的情况就没有处理,不知道大家在自己的项目中是如何处理的?我的实验是,IE6的设置会影响应用路径的编码方式,例如地址栏中请求一个中文JSP页面,如:http://localhost:8080/helloapp/编辑.jsp,IE默认是勾选"以UTF-8发送URL"项的,那么按照我上面总结的处理方式,这个请求可以正常显示页面,如图:

    如果取消IE的这个选项,那么浏览器会以GBK编码应用路径的中文,得到的结果如图:

    按照我上面的设置,这里如果将Tomcat的URIEncoding设置为GBK,则也可以正常显示页面。对于FireFox3.0,则是以UTF-8编码。

    最后,回到我的题目,向大家讨教下,IE6的“以UTF-8发送URL”选项设置对请求页面字符编码有影响吗?欢迎讨论!

     

    我的测试代码共享给大家:),使用的是struts1.2,struts的jar包,大家可以去apache下载。

     

    这里推荐个链接,有兴趣的可以深入了解更多字符集、编码的问题。

    http://hideto.javaeye.com/blog/97803

  • 相关阅读:
    线段树专辑—— pku 1436 Horizontally Visible Segments
    线段树专辑——pku 3667 Hotel
    线段树专辑——hdu 1540 Tunnel Warfare
    线段树专辑—— hdu 1828 Picture
    线段树专辑—— hdu 1542 Atlantis
    线段树专辑 —— pku 2482 Stars in Your Window
    线段树专辑 —— pku 3225 Help with Intervals
    线段树专辑—— hdu 1255 覆盖的面积
    线段树专辑—— hdu 3016 Man Down
    Ajax跨域访问
  • 原文地址:https://www.cnblogs.com/pricks/p/1601874.html
Copyright © 2011-2022 走看看