乱码
服务器JSP编码
pageEncoding
是jsp文件本身的编码,
第一阶段是jsp编译成.java,它会根据pageEncoding的设定读取jsp,(jsp文件的编码,pageEncoding是否一致),结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding设定错了,或没有设定(在JSP标准的语法中,如果pageEncoding属性存在,那么JSP页面的字符编码方式就由pageEncoding决定,否则就由contentType属性中的charset决定,如果charset也不存在,JSP页面的字符编码方式就采用默认的ISO-8859-1。),出来的就是中文乱码。该参数还有一个功能,就是在JSP中不指定contentType参数,也不使用response.setCharacterEncoding方法时,指定对服务器响应进行重新编码的编码。
contentType
contentType的charset是指服务器发送给客户端时的内容编码
注:
可见,pageEncoding和contentType都可以设置JSP源文件和响应正文中的字符集编码。但也有区别:
设置JSP源文件字符集时,优先级为pageEncoding>contentType。如果都没有设置,默认ISO-8859-1。
设置响应输出的字符集时,优先级为contentType>pageEncoding。如果都没有设置,默认ISO-8859-1。
客户端浏览器编码
URL编码
1. 在IE中输入网址http://www.baidu.com/s?wd=春节
查询字符串的编码:
IE:用的是操作系统的编码。
Chrome:UTF-8
FIREFOX:UTF-8
2. 在页面链接中:<a href=” http://www.baidu.com/s?wd=春节”>点我</a>
由网页编码决定,都是由Content-Type指定
GET请求
由网页编码决定,都是由Content-Type指定
POST请求
由网页编码决定,都是由Content-Type指定
Jquery ajax请求
在发送请求时,ajax会自动把查询字符串进行UTF-8编码。
$.ajax({
data:[{key=value}]//这样才会自动编码,如果是key=value&。。。自己拼装的则不会编码
});
注:jquery内部会调用jQuery.param方法对参数encode(执行本应浏览器处理的encode)。
编码处理
GET请求
对于GET方式处理编码有两种方法:(服务器为:Tomcat)
1. 代码实现,使用硬编码:
new String(request.getParameter(“name”).getBytes(“iso-8859-1”),”客户端编码方式”);
2. 服务器下的配置(也就是把硬编码的操作交给了Tomcat了)
在server.xml下配置:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding='UTF-8'/>
或者:
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI='TRUE'/>
Ø URIEncoding是对所有GET方式的请求的数据进行统一的重新编码。
Ø useBodyEncodingForURI则是根据响应该请求的页面的request.setCharacterEncoding参数对数据进行的重新编码,不同的页面可以有不同的重新编码的编码, ,在默认情况下,该参数为false。
POST请求
request.setCharacterEncoding(arg0); 只针对POST起作用
Javascript编码函数
1. escape()
不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值。比如"春节"的返回结果是%u6625%u8282,也就是说在Unicode字符集中,"春"是第6625个(十六进制)字符,"节"是第8282个(十六进制)字符。
它的规则是,escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z,对其他所有字符进行编码。在\u0000到\u00ff之间的符号被转成%xx的形式,其余符号被转成%uxxxx的形式。对应的解码函数是unescape()。
注:首先,无论网页的原始编码是什么,一旦被Javascript编码,就都变为unicode字符。也就是说,Javascipt函数的输入和输出,默认都是Unicode字符。
其次,escape()不对"+"编码。但是我们知道,网页在提交表单的时候,如果有空格,则会被转化为+字符。服务器处理数据的时候,会把+号处理成空格。所以,使用的时候要小心。
encodeURI()
encodeURI()是Javascript中真正用来对URL编码的函数。
编码后,它输出符号的utf-8形式,并且在每个字节前加上%。
它对应的解码函数是decodeURI()。
需要注意的是,它不对单引号'编码。
encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z
encodeURIComponent()
与encodeURI()的区别是,它用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。
encodeURIComponent不编码字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z它对应的解码函数是decodeURIComponent()。
有时为什么会使用两次js编码
因为第一次编码,你的参数内容便不带有多字节字符了,成了纯粹的 Ascii 字符串。(这里把编第一次的结果叫成 [STR_ENC1] 好了。[STR_ENC1] 是不带有多字节字符的)
再编一次后,提交,接收时容器自动解一次(容器自动解的这一次,不管是按 GBK 还是 UTF-8 还是 ISO-8859-1 都好,都能够正确的得到 [STR_ENC1])
然后,再在程序中实现一次 decodeURIComponent (Java中通常使用 java.net.URLDecoder(***, "UTF-8")) 就可以得到想提交的参数的原值。
举个栗子:
String str1 = URLEncoder.encode("程序员","utf-8");//假设为浏览器的第一次编码
String str2 = URLEncoder.encode(str1,"utf-8"); //浏览器第二次编码
String deStr1 = URLDecoder.decode(str2,"gbk");
//服务器进行解码,不论是什么编码都能得到正确的浏览器第一次的编码
String deStr2 = URLDecoder.decode(deStr1,"utf-8");//最后得到正确的字符串