参考:
关于URL编码
##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编码情况
##2.解决方案
URL可以不经编码的字符有:
//[0-9a-zA-Z]
//$-_.+!*'(),
//某些保留字
总结有以下几种方案。
###2.1.Javascript函数:escape() [已验证]
<script type="text/javascript">
//编码:将需要编码的字符编码成Unicode值
var url = escape("http://www.baidu.com/春节");
document.write(url + "
");
//解码
var url = unescape(url);
document.write(url);
</script>
//escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z
//古老函数,不提倡使用
result:
http%3A//www.baidu.com/%u6625%u8282
http://www.baidu.com/春节
###2.2.Javascript函数:encodeURI() [已验证]
encodeURI()是Javascript中真正用来对URL编码的函数。
<script type="text/javascript">
//编码:输出符号的utf-8形式,并且在每个字节前加上%,注意是两次。
var url = encodeURI("http://www.baidu.com/春节");
document.write(url + "
");
//解码
var url = decodeURI(url);
document.write(url);
</script>
//encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a- z,A-Z
//建议使用
result:
http://www.baidu.com/%E6%98%A5%E8%8A%82
http://www.baidu.com/春节
###2.3.Javascript函数:encodeURIComponent() [已验证]
encodeURIComponent()用于对URL的组成部分进行个别编码,而不用于对整个URL进行编码。
<script type="text/javascript">
//编码:输出符号的utf-8形式,并且在每个字节前加上%,注意是两次。
var url = encodeURIComponent("http://www.baidu.com/春节");
document.write(url + "
");
//解码
var url = decodeURIComponent(url);
document.write(url);
</script>
//encodeURIComponent不编码字符有71个:!, ',(,),*,-,.,_,~,0-9,a-z,A-Z
//建议使用
result:
http%3A%2F%2Fwww.baidu.com%2F%E6%98%A5%E8%8A%82
http://www.baidu.com/春节
###2.4.java.net.URLEncoder和java.net.URLDncoder [未验证]
HTML 格式编码的实用工具类。该类包含了将 String 转换为 application/x-www-form-urlencoded MIME 格式的静态方法。
对 String 编码时,使用以下规则:
例如,使用 UTF-8 编码机制,字符串 “The string ü@foo-bar” 将转换为 “The+string+%C3%BC%40foo-bar”,因为在 UTF-8 中,字符 ü 编码为两个字节,C3 (十六进制)和 BC (十六进制),字符 @ 编码为一个字节 40 (十六进制)。
//编码
java.net.URLEncoder.encode(URIString, "UTF-8");
//解码
java.net.URLDecoder.decode(URIString, "UTF-8");
//不推荐使用
###2.5.Tomcat/conf/server.xml的URIEncoding [已验证]
<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.只是对请求参数进行了转码,如果请求路径中有中文,则无法处理。