URL地址中中文乱码详解(javascript中encodeURI和decodeURI方法、java.net.URLDecoder.encode、java.net.URLDecoder.decode)
引言: 在Restful类的服务设计中,经常会碰到需要在URL地址中使用中文作为的参数的情况,这种情况下,一般都需要正确的设置和编码中文字符信息。乱码问题就此产生了,该如何解决呢?且听本文详细道来。
1. 问题的引出
在Restful的服务设计中,查询某些信息的时候,一般的URL地址设计为: get /basic/service? keyword=历史 , 之类的URL地址。 但是,在实际的开发和使用中,确是有乱码情况的发生,在后台的读取keyword信息为乱码,无法正确读取。
2. 乱码是如何产生的?
5. 后台如何正确解析中文字符信息?
进入后台的信息,在经过二次encodeURI()之后,直接读取是无法后去正确的信息的。 需要继续如下处理:
- URLDecoder.decode("chinese string","UTF-8")
URLDecoder的decode(String str,String ecn)方法有两个参数,第一个参数为待解码的字符串,第二个参数为解码时的对应编码。
6. encodeURI, encodeURIComponent, escape
6.1 escape()函数
escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。
返回值:已编码的 string 的副本。其中某些字符被替换成了十六进制的转义序列。
说明 :该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( ) 。其他所有的字符都会被转义序列替换。所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是%20。不会被此方法编码的字符: @ * / +
6.2 encodeURI() 方法
把URI字符串采用UTF-8编码格式转化成escape格式的字符串。不会被此方法编码的字符:! @ # $& * ( ) = : / ; ? + '
6.3 encodeURIComponent() 方法
把URI字符串采用UTF-8编码格式转化成escape格式的字符串。与encodeURI()相比,这个方法将对更多的字符进行编码,比如 / 等字符。所以如果字符串里面包含了URI的几个部分的话,不能用这个方法来进行编码,否则 / 字符被编码之后URL将显示错误。
不会被此方法编码的字符:! * ( ) '
因此,对于中文字符串来说,如果不希望把字符串编码格式转化成UTF-8格式的(比如原页面和目标页面的charset是一致的时候),只需要使用escape。如果你的页面是GB2312或者其他的编码,而接受参数的页面是UTF-8编码的,就要采用encodeURI或者encodeURIComponent。
7. 另一种处理URL的中文乱码方案
请求端的中字符有encodeURI进行一次转码,如:
var url="/ajax?name="+encodeURI(name);
服务器端代码:
name=new String(name.getBytes("iso8859-1"),"UTF-8");
注: name为获得的字符串,iso8859-1为项目的默认字符编码,如果为中文编码gbk,gb2312等则不用这一步进行处理.
分析: 经过程序验证,结果可行的。 由此可知,浏览器本身默认的编码方式是iso8859-1的方式,即使使用了encodeURI进行了utf-8编码处理,主要的字符串内容,比如ascii字符和可见字符都还是基于iso8859-1浏览器自身的字符。原因就是这些字符在编码上和UTF-8字符串是重合的。而encodeURI之类的转义函数主要解决,特殊字符%,/之类的字符的转义问题。
javascript中encodeURI和decodeURI方法
一、基本概念
encodeURI和decodeURI是成对来使用的,因为浏览器的地址栏有中文字符的话,可以会出现不可预期的错误,所以可以encodeURI把非英文字符转化为英文编码,decodeURI可以用来把字符还原回来。encodeURI方法不会对下列字符进行编码:":"、"/"、";" 和 "?",encodeURIComponent方法可以对这些字符进行编码。
decodeURI()方法相当于java.net.URLDecoder.decode(URIString, "UTF-8");
encodeURI()方法相当于java.net.URLEncoder.encode(URIString, "UTF-8");
二、例子
<script type="text/javascript">
var uriStr = "http://www.baidu.com?name=张三&num=001 zs";
var uriec = encodeURI(uriStr);
document.write("编码后的" + uriec);
var uridc = decodeURI(uriec);
document.write("解码后的" + uridc);
</script>
编码后的http://www.baidu.com?name=%E5%BC%A0%E4%B8%89&num=001%20zs
解码后的http://www.baidu.com?name=张三&num=001 zs
java jdk中说明:java.net.URLEncoder.encode(URIString, "UTF-8");
HTML 格式编码的实用工具类。该类包含了将 String 转换为 application/x-www-form-urlencoded MIME 格式的静态方法。有关 HTML 格式编码的更多信息,请参阅 HTML 规范。
对 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 (十六进制)。
encode
public static String encode(String s,
String enc)
throws UnsupportedEncodingException
- 使用指定的编码机制将字符串转换为
application/x-www-form-urlencoded格式。该方法使用提供的编码机制获取不安全字符的字节。注:World Wide Web Consortium Recommendation 声明应使用 UTF-8。如果不使用该编码,可能造成不兼容性。
-
- 参数:
s- 要转换的String。enc- 所支持的字符编码名称。- 返回:
- 已转换的
String。 - 抛出:
UnsupportedEncodingException- 如果不支持指定的编码
jdk中说明:java.net.URLDecoder.decode(URIString, "UTF-8");
HTML 格式解码的实用工具类。该类包含了将 String 从 application/x-www-form-urlencoded MIME 格式解码的静态方法。
该转换过程正好与 URLEncoder 类使用的过程相反。假定已编码的字符串中的所有字符为下列之一:"a" 到 "z"、"A" 到 "Z"、"0" 到 "9" 和 "-"、"_"、"." 以及 "*"。允许有 "%" 字符,但是将它解释为特殊转义序列的开始。
转换中使用以下规则:
- 字母数字字符 "
a" 到 "z"、"A" 到 "Z" 和 "0" 到 "9" 保持不变。 - 特殊字符 "
."、"-"、"*" 和 "_" 保持不变。 - 加号 "
+" 转换为空格字符 ""。 - 将把 "
%xy" 格式序列视为一个字节,其中 xy 为 8 位的两位十六进制表示形式。然后,所有连续包含一个或多个这些字节序列的子字符串,将被其编码可生成这些连续字节的字符所代替。可以指定对这些字符进行解码的编码机制,或者如果未指定的话,则使用平台的默认编码机制。
该解码器处理非法字符串有两种可能的方法。一种方法是不管该非法字符,另一种方法是抛出 IllegalArgumentException 异常。解码器具体采用哪种方法取决于实现。
decode
public static String decode(String s,
String enc)
throws UnsupportedEncodingException
- 使用指定的编码机制对
application/x-www-form-urlencoded字符串解码。给定的编码用于确定任何 "%xy" 格式的连续序列表示的字符。注:World Wide Web Consortium Recommendation 声明应使用 UTF-8。如果不使用该编码,可能造成不兼容性。
-
- 参数:
s- 要解码的Stringenc- 所支持的字符编码的名称。- 返回:
- 新解码的
String - 抛出:
UnsupportedEncodingException- 如果需要参考字符编码,而指定的字符编码不被支持
对于Post请求,只需在Servlet或者jsp中写入如下代码就可以把解决从表单中传入的中文乱码问题
request.setCharacterEncoding("utf-8");
而对于Get请求,因为请求参数会被附加到地址栏的URL之后,所以不能用上面的处理方法。应该这样:
String str=request.getQueryString();
//使用URLDecoder解码字符串
String str1=java.net.URLDecoder.decode(str,"utf-8");
String[] paraStrings=str1.split("&");
//paraStrings[0]就是第一个参数,依次类推...
for(String paraString : paraStrings)
{
String[] nameValue=paraString.split("=");
//nameValue[0]就是表单的name,nameValue[1]就是表单name对应的值
}
还有一种方法就是获取请求参数之后对请求参数值重新编码,也就是先将其转换成字节数组,再将字节数组重新解码成字符串。
String str=request.getParameter("name");
byte[] bytes=str.getBytes("ISO-8859-1");
String name=new String(bytes,"utf-8");
URL地址中中文乱码详解(javascript中encodeURI和decodeURI方法、java.net.URLDecoder.encode、java.net.URLDecoder.decode)的更多相关文章
- java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")
http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
- 详解 javascript中offsetleft属性的用法(转)
详解 javascript中offsetleft属性的用法 转载 2015-11-11 投稿:mrr 我要评论 本章节通过代码实例介绍一下offsetleft属性的用法,需要的朋友可以做一 ...
- 详解javascript中的this对象
详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...
- (转载)详解Javascript中prototype属性(推荐)
在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不 ...
- 详解JavaScript中的Url编码/解码,表单提交中网址编码
本文主要针对URI编解码的相关问题做了介绍,对Url编码中哪些字符需要编码.为什么需要编码做了详细的说明,并对比分析了Javascript 中和 编解码相关的几对函数escape / unescape ...
- 详解JavaScript中的原型
前言 原型.原型链应该是被大多数前端er说烂的词,但是应该还有很多人不能完整的解释这两个内容,当然也包括我自己. 最早一篇原型链文章写于2019年07月,那个时候也是费了老大劲才理解到了七八成,到现在 ...
- 【转】详解JavaScript中的异常处理方法
有三种类型的编程错误:(1)语法错误和(2)运行时错误(3)逻辑错误:语法错误: 语法错误,也被称为解析错误,在编译时进行传统的编程语言,并出现在JavaScript解释时. 例如,下面一行将导致一个 ...
- 详解JavaScript中的Event Loop(事件循环)机制
前言 我们都知道,javascript从诞生之日起就是一门单线程的非阻塞的脚本语言.这是由其最初的用途来决定的:与浏览器交互. 单线程意味着,javascript代码在执行的任何时候,都只有一个主线程 ...
随机推荐
- C语言讲解命令行参数
命令行(command line):是在命令行环境中,用户为运行程序输入命令的行. 命令行参数(command-line argument): 是同一行的附加项. C编译器允许main()没有参数或者 ...
- 了解Linux系统
++++++++++++++++++++++++++++++++++++++++++++++++++++ 有用的参考链接: 带你初识Linux操作系统:https://www.linuxidc.com ...
- Kibana6.x.x——源码发布
从官方GitHub上克隆下来的源码自己如何发布? 我在Ubuntu系统中进行的开发,安装了yarn. 执行build命令为:$ yarn build 执行release命令为:$ yarn relea ...
- Common Subsequence(最长公共子序列)
A subsequence of a given sequence is the given sequence with some elements (possible none) left out. ...
- IOS开发-基于WebDriverAgent代理服务,实现iOS手机app自动化测试的框架搭建
导引 iOS自动化测试一直使用的appium,iOS系统升级至10.0 Xcode8.0之后,改用WebDriverAgent代理服务作为server,编写了一套基于WebDriverAgent服务 ...
- C语言一些易混淆的概念
①数组指针和指针数组 1. 数组指针用于指向一个数组,数组名是数组首元素的地址(数组名为数组首元素类型且指向首元素的指针,如int array[5] ,array为指向array[0]的指针且类型为i ...
- 多线程编程_CyclicBarrier
1.类说明: 一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 Cycl ...
- AndroidAPI
1词典 百度翻译 http://api.fanyi.baidu.com/api/trans/product/index 百度翻译支持多种语言互相翻译,包含PHP, JS, Python, C, Jav ...
- Murano Weekly Meeting 2015.08.11
Meeting time: 2015.August.11th 1:00~2:00 Chairperson: Serg Melikyan, PTL from Mirantis Meeting summ ...
- (转)python 列表与元组的操作简介
python 列表与元组的操作简介 原文:https://www.cnblogs.com/QG-whz/p/4782809.html 阅读目录 列表 list函数 列表的基本操作 列表方法 元组 tu ...