IE6的“以UTF-8发送URL”选项设置对请求页面字符编码有影响吗?

本文详细探讨了在使用Tomcat6.0作为servlet容器时遇到的中文乱码问题,并针对GET和POST提交方式的不同场景提供了具体的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      最近又碰到了中文乱码问题,这里我没有把数据库牵扯进来,先说下我的环境,servlet容器使用Tomcat6.0,浏览器FireFox3.0、IE6,涉及字符编码设置的地方我的思路就是编码的地方都统一使用UTF-8,具体配置如下:

1.所有页面的charset设置为UTF-8。

2.Tomcat的URIEncoding默认是ISO-8859-1,而我设置为UTF-8,主要是想解决中文命名的文件以及请求以get方式提交有可能出现的乱码问题。

3.添加过滤器,调用request.setCharacterEncoding("utf-8")方法将request的字符集设定为utf-8,解决请求以post方式提交的乱码问题。

其实这样的设置貌似是不会再出现乱码问题了,不过,问题依旧来了 ,如果我在浏览器的地址栏中输入中文参数提交,返回的页面却出现了乱码。真搞不明白到底是哪里出了问题!说起来对中文乱码的问题一直是一支半解,出现乱码了,网上搜罗了一大堆资料,按照网上的配置,问题到是解决了,不过原理却搞的很模糊,一个请求发送到服务器,服务器业务逻辑处理后返回一个页面,这中间涉及的字符集转换,编码,解码过程一概不清楚。这次,折腾了半天,总算是更进一步了解了字符编码问题,这里做个总结。

先看我的总结,有不对的地方欢迎批评。

首先我们看下,一个请求响应的流程

 

浏览器 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(解码)

这个过程也相当于我们使用如下的语句

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

根据API的解释,先将变量值以UTF-8字符集编码转换为字节序列,再以ISO-8859-1字符集解码字节数组,构造出新的字符串对象。

等价于以下方式:

String code = "编码";
code = URLEncoder.encode(code,"UTF-8");
code = URLDecoder.decode(code,"ISO-8858-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.页面链接中传递中文参数

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

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

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

<%
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.iteye.com/blog/97803

 

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>400 错误 - phpstudy</title> <meta name="keywords" content=""> <meta name="description" content=""> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <meta HTTP-EQUIV="pragma" CONTENT="no-cache"> <meta HTTP-EQUIV="Cache-Control" CONTENT="no-store, must-revalidate"> <meta HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"> <meta HTTP-EQUIV="expires" CONTENT="0"> <style> body{ font: 16px arial,'Microsoft Yahei','Hiragino Sans GB',sans-serif; } h1{ margin: 0; color:#3a87ad; font-size: 26px; } .content{ width: 45%; margin: 0 auto; } .content >div{ margin-top: 200px; padding: 20px; background: #d9edf7; border-radius: 12px; } .content dl{ color: #2d6a88; line-height: 40px; } .content div div { padding-bottom: 20px; text-align:center; } </style> </head> <body> <div class="content"> <div> <h1>HTTP 400 - Bad Request</h1> <dl> <dt>错误说明:因为错误的语法导致服务器无法理解请求信息。</dt> <dt>原因1:客户端发起的请求不符合服务器对请求的某些限制,或者请求本身存在一定的错误。</dt> <dd>解决办法:</dd> <dd>链接中有特殊字符或者链接长度过长导致,请对应修改.</dd> <dt>原因2:request header 或者 cookie 过大所引起</dt> <dd>解决办法:</dd> <dd>crtl+shift+delete 快捷键清除cookie.</dd> </dl> <div>使用手册,视频教程,BUG反馈,官网地址: <a href="https://www.xp.cn" target="_blank">www.xp.cn</a> </div> </div> </div> </body> </html>
最新发布
04-02
### 关于HTTP 400错误的原因及解决方法 HTTP 400错误通常表示客户端发送了一个不合法或者服务器无法理解的请求。这种错误可能由多种因素引起,例如表单数据格式错误、URL编码问题、请求头不符合标准等。 #### 可能原因分析 1. **表单上传问题** 当通过`POST`方式提交表单时,如果表单字段名称或值存在非法字符,可能会导致服务器拒绝接收请求并返回400错误。例如,在某些情况下,表单字段名中包含特殊字符可能导致解析失败[^1]。 2. **Nginx配置不当** 如果Nginx未正确配置,也可能引发此类问题。比如,当请求体过大而超出Nginx允许的最大大小(`client_max_body_size`)时,会触发400错误。此外,连接关闭设置不合理也可能是原因之一。 3. **PHP-FPM处理异常** 后端PHP-FPM服务可能出现故障,未能正常响应来自前端代理(Nginx)转发过来的有效请求。这包括但不限于PHP脚本执行超时、内存不足等问题[^3]。 4. **Discuz特定场景下的Bad Request** 对于像Discuz这样的应用框架来说,“Bad Request”还可能源于内部逻辑判断失误或者是插件扩展引入的新漏洞所致。例如DIY功能保存失败以及SEO设置修改受限等情况均被报告与此类错误有关联[^4]。 #### 解决方案建议 针对上述提到的各种可能性提供相应解决方案: - #### 调整Nginx参数限制 修改站点对应的虚拟主机配置文件中的几个重要指令来适应实际需求: ```nginx client_max_body_size 8M; proxy_connect_timeout 60s; proxy_read_timeout 90s; fastcgi_buffers 8 16k; fastcgi_buffer_size 32k; ``` - #### 检查PHP环境状态 查看php.ini里关于session启动的相关选项是否有误;确认error_reporting级别是否过高以至于暴露敏感信息给外部访问者看到; ```ini error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors = Off log_errors = On max_execution_time = 30 memory_limit = 128M post_max_size = 8M upload_max_filesize = 8M ``` - #### 审核应用程序代码质量 特别关注那些涉及复杂输入验证过程的部分程序段落是否存在潜在缺陷。必要时候借助单元测试工具进行全面覆盖检测以发现隐藏风险点。 - #### 更新软件版本至最新稳定版 使用较旧版本可能存在已知安全性和兼容性方面的问题,及时升级能够有效减少不必要的麻烦发生几率。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值