ajax验证中文报错解决,ajax中文乱码问题的总结

JavaScript部分:

首先引入ajax.js文件,然后编写当按钮点击的时候的要执行的代码:

"text/javascript"src="ajax.js">

"text/javascript">

functioncheckUserName(tagID){

//获取文本框中输入的值

varuserName=document.getElementByIdx_x(tagID).value;

//对中文进行URL编码

①varurl="ajax.do?"+encodeURI("userName="+userName);

//data是从服务端返回来的数据

doGet(url,function(data){

document.getElementByIdx_x("warning").innerHTML=data;

});

}

页面效果:

a4c26d1e5885305701be709a3d33442f.png

当在文本框中输入“张三”后,点击验证后,javaScript代码执行到 ① 之后,url的值就变成了“ajax.do?userName=张三”,可以通过firefox浏览器的firebug插件进行断点调试,得到发送的url的值。

这里为什么没有使用encodeURIComponent()函数呢?这是因为encodeURIComponent函数会将”=”变成“=”,“?”变成”?”, 如果有多个参数的话会用到“&”符号,同样也会被转换,而这些字符不用转换也可以提交,所以这里使用了encodeURI,这个函数不会对”?”,”=”,”&”进行转换。后面的“张三”就是“张三”两个汉字按照UTF-8字符集进行URL编码之后的结果

5. 在服务端取得发送过来的数据

编写一个Servlet,这个Servlet的映射是 /ajax.do,其中的doGet方法如下:

public voiddoPost(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

//告诉客户端响应的信息的编码格式是UTF-8

response.setContentType("text/html;charset=UTF-8");

②String userName=request.getParameter("userName");

PrintWriter out=response.getWriter();

out.print("您要验证的用户名是:"+userName+",该用户名可以使用");

}

我们在②处放置一个断点,然后以断点的方式启动Tomcat,提交后程序进入断点处我们发现取得的userName的值是:“??????”,为什么会是乱码?

我们分析一下,客户端Ajax想服务器发送的请求是

”ajax.do?userName=张三”,那么服务器上的

request.getParameter()方法在取参数值的时候,首先要进行URL解码(其实就是去掉字符当中的“%“),解码之后将只剩下的字节部分按照Tomcat在内部默认的ISO-8859-1字符集的方式转换成字符串,于是乱码开始在这里出现 了。因为发送过来的字节在去掉%后剩下的字节应该按照UTF-8转换字符串才对,但是却采用了ISO-8859-1,于是乱码产生了。

那么知道原因之后,解决起来就很容易了。既然是按照ISO-8859-1转换得到的字符串,那我们就得到这个字符串还原为ISO-8859-1的字节,然后再将字节按照正确的UTF-8转换为字符串,这样就得到了正确的字符了,修改Servlet中的代码如下:

public voiddoPost(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

//告诉客户端响应的信息的编码格式是UTF-8

response.setContentType("text/html;charset=UTF-8");

System.out.println("进入Servlet");

String userName=request.getParameter("userName");

userName=newString(userName.getBytes("iso-8859-1"),"UTF-8");

System.out.println(userName);

PrintWriter out=response.getWriter();

out.print("您要验证的用户名是:"+userName+",该用户名可以使用");

}

客户端响应为:

a4c26d1e5885305701be709a3d33442f.png

6. 试一试将提交方式改成POST方式

在ajax.js文件中添加一个函数,该函数专门用于提交POST请求

functiondoPost(url,submitData,callBack){

varrequest=createXmlHttp();

request.onreadystatechange=function(){

if(request.readyState==4 && request.status==200){

//注意我们定义回调函数的时候要多加一个参数接收返回的数据

callBack(request.responseText);

}

};

request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

request.open("POST",url);

request.send(submitData);

}

修改页面上的javaScript代码:

"text/javascript"src="ajax.js">

"text/javascript">

functioncheckUserName(tagID){

//获取文本框中输入的值

varuserName=document.getElementByIdx_x(tagID).value;

//data是从服务端返回来的数据

doPost("ajax.do","userName="+userName,function(data){

document.getElementByIdx_x("warning").innerHTML=data;

});

}

当我们发送post请求的时候,尽管我们为请求头设置了

application/x-www-form-urlencoded,但是发送的数据并没有进行URL编码,而传统的将form表单的提交方式设置成post,在提交的时候会自动进行URL编码。

所以Ajax中的post请求时将数据原封不动的传递到了服务器上,所以只需要调用reqeust.setCharacterEncoding() 设置正确的编码集后,就可以取出数据了。

7. 最佳解决方案

前面的方式我们虽然分别解决了GET方式和POST方式的中文问题,但是需要分开进行处理,并且对于不同的服务器,默认的编码集是不同的,这样对于GET方式我们进行的手工转码就不能通用了。

那么不管是Get请求还是POST,有没有可以统一的解决方案?我们可以做如下的处理:

将提交的数据使用javaScript的encodeURI()进行两次URL编码

服务端进行一次URL 解码即可

这种方式的优点是与客户端网页的编码集无关,与服务器的默认编码集无关,而且能够兼容几乎所有的浏览器。

下面以GET方式为例来理解分析全过程:

修改javaScript代码为:

"text/javascript"src="ajax.js">

"text/javascript">

functioncheckUserName(tagID){

//获取文本框中输入的值

varuserName=document.getElementByIdx_x(tagID).value;

//data是从服务端返回来的数据

varurl="ajax.do? userName="+encodeURI(encodeURI(userName));

doGet(,function(data){

document.getElementByIdx_x("warning").innerHTML=data;

});

}

Servlet代码修改为:

public voiddoPost(HttpServletRequest request, HttpServletResponse response)

throwsServletException, IOException {

//告诉客户端响应的信息的编码格式是UTF-8

response.setContentType("text/html;charset=UTF-8");

String userName=request.getParameter("userName");

userName=URLDecoder.decode(userName,"UTF-8");

System.out.println(userName);

PrintWriter out=response.getWriter();

out.print("您要验证的用户名是:"+userName+",该用户名可以使用");

}

运行后,在各种浏览器中都没有出现乱码问题。换成POST方式,也没有出现乱码问题。页面如果换成GBK编码,也没有出现乱码问题.

为什么这种方式没有出现问题,为什么要进行两次 encodeURI?我们只需要跟踪一下提交的数据即可:

假如我们提交的是“张三”:

①我们第一次进行encodeURI之后的结果为:

李四

②第二次进行encodeURI之后的结果为:

李四

③我们对比一下两个值,发现第一次URL编码后中间有%,而第二次URL编码后将第一次编码结果中的%替换成了%,所以最终发送的数据为:

ajax.do?userName=李四

④在服务端的Servlet中,我们通过调用request.getParameter(“userName”)取值的时候,getParameter方法会对李四进行URL解码,解码后的结果为李四,也就是将%换成了%,那么此时Tomcat服务器按照默认的iso-8859-1转换的字符串的时候根本就没有做任何变换,还是李四

⑤当我们再次进行URL解码的时候即:URLDecoder.decode(userName,"UTF-8"),此时去掉其中的%后变成了E69D8EE59B9B,这正好是”张三”的UTF-8编码,所以使用UTF-8码转换成字符串“张三“.

从整个过程看来,这种方式的优势在于与页面的编码无关,也与服务器所使用的编码集无关。我们需要做的只需要将提交的数据(不管是POST的数据还是GET的数据),进行两次encodeURI即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值