##1.URL中文编码乱码原因
以下这段话引自网络标准RFC 1738以及关于URL编码
“…Only alphanumerics [0-9a-zA-Z], the special characters “$-_.+!*’(),” [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL.”
“只有字母和数字[0-9a-zA-Z]、一些特殊符号”$-_.+!*’(),"[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。"
这意味着,如果URL中有汉字,就必须编码后使用。但是麻烦的是,RFC 1738没有规定具体的编码方法,而是交给应用程序(浏览器)自己决定。这导致"URL编码"成为了一个混乱的领域。
通过解读关于URL编码,总结有以下几种URL编码情况
网址路径中包含汉字。
查询字符串包含汉字。
Get方法生成的URL包含汉字。
Ajax调用的URL包含汉字。
##2.解决方案
URL可以不经编码的字符有:
1 //[0-9a-zA-Z]
2 //$-_.+!*'(),
3 //某些保留字
总结有以下几种方案。
###2.1.Javascript函数:escape() [已验证]
1 <script type="text/javascript">
2 //编码:将需要编码的字符编码成Unicode值
3 var url = escape("http://www.baidu.com/春节");
4 document.write(url + "<br>");
5 //解码
6 var url = unescape(url);
7 document.write(url);
8 </script>
9
10 //escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z
11 //古老函数,不提倡使用
result:
1 http%3A//www.baidu.com/%u6625%u8282
2 http://www.baidu.com/春节
###2.2.Javascript函数:encodeURI() [已验证]
encodeURI()是Javascript中真正用来对URL编码的函数。
1 <script type="text/javascript">
2 //编码:输出符号的utf-8形式,并且在每个字节前加上%,注意是两次。
3 var url = encodeURI("http://www.baidu.com/春节");
4 document.write(url + "<br>");
5 //解码
6 var url = decodeURI(url);
7 document.write(url);
8</script>
9
10 //encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a- z,A-Z
11 //建议使用
result:
1 http://www.baidu.com/%E6%98%A5%E8%8A%82
2 http://www.baidu.com/春节
###2.3.Javascript函数:encodeURIComponent() [已验证]
encodeURIComponent()用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。
1 <script type="text/javascript">
2 //编码:输出符号的utf-8形式,并且在每个字节前加上%,注意是两次。
3 var url = encodeURIComponent("http://www.baidu.com/春节");
4 document.write(url + "<br>");
5 //解码
6 var url = decodeURIComponent(url);
7 document.write(url);
8 </script>
9
10 //encodeURIComponent不编码字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z
11 //建议使用
result:
1 http%3A%2F%2Fwww.baidu.com%2F%E6%98%A5%E8%8A%82
2 http://www.baidu.com/春节
###2.4.java.net.URLEncoder和java.net.URLDncoder [未验证]
HTML 格式编码的实用工具类。该类包含了将 String 转换为 application/x-www-form-urlencoded MIME 格式的静态方法。
对 String 编码时,使用以下规则:
字母数字字符 “a” 到 “z”、“A” 到 “Z” 和 “0” 到 “9” 保持不变。
特殊字符 “.”、"-"、"*" 和 “_” 保持不变。
空格字符 " " 转换为一个加号 “+”。
所有其他字符都是不安全的,因此首先使用一些编码机制将它们转换为一个或多个字节。然后每个字节用一个包含 3 个字符的字符串 “%xy” 表示,其中 xy 为该字节的两位十六进制表示形式。推荐的编码机制是 UTF-8。但是,出于兼容性考虑,如果未指定一种编码,则使用相应平台的默认编码。
例如,使用 UTF-8 编码机制,字符串 “The string ü@foo-bar” 将转换为 “The+string+%C3%BC%40foo-bar”,因为在 UTF-8 中,字符 ü 编码为两个字节,C3 (十六进制)和 BC (十六进制),字符 @ 编码为一个字节 40 (十六进制)。
1 //编码
2 java.net.URLEncoder.encode(URIString, "UTF-8");
3 //解码
4 java.net.URLDecoder.decode(URIString, "UTF-8");
5 //不推荐使用
###2.5.Tomcat/conf/server.xml的URIEncoding [已验证]
1 <!-- 这种方式缺点显而易见,换了服务器就要更改,有时候忘记也是很常见的事情。 -->
2 <Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" URIEncoding="UTF-8">
###2.6.HttpServletRequestWrapper+Filter [未验证]
思路:
1. 创建一个类继承HttpServletRequestWrapper,重写getParameter、getParameterValues和getParameterMap,对参数进行转码。
2. 创建一个过滤器,获取request对象,调用HttpServletRequestWrapper进行包装解密。
缺陷:
1.只是对请求参数进行了转码,如果请求路径中有中文,则无法处理。
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。