在进行web开发的时候经常会遇到乱码的问题,乱码一般出现在:
1.写在jsp文件中的中文变成乱码
2.页面的中文都变成乱码
3.后台通过request.getParameter()乱码
编码的基础知识
计算机只能以字节为单位存储和传输信息,而人需要看的是字符串,字节和字符串之间的对应关系就是字符集,例如字符“中”使用UTF-8字符集映射的字节为:E4 B8 AD 三个字节,同样反过来,这三个字节通过UTF-8字符集映射便能得到“中”这个字符,不同的字符集映射规则不一样,能表示的范围也不一样,例如“中”在GB2312中对应的字节表示为:D6 D0 两个字节,字符和字节之间的转换,描述为编码和解码:
l 字符->字节:编码,例如:“中”的UTF-8编码为 E4 B8 AD
l 字节->字符:解码,例如:字节数组D0 D6根据GB2312解码为字符“中”
还有一类编码称为URI编码和URI解码,不过URI编码和解码不是字符串和字节流之间的转换,而是由一个字符串表示另一个字符串,例如:
l “中”的UTF-8 URI编码为 %E4%B8%AD
l 字符串%E4%B8%AD根据UTF-8进行URI解码为字符“中”
可以看出来,
URI编码就是将一个字符串用%+对应字符集的编码组织的字符串来表示的,在java中String类有两个常用的方法进行编码和解码:
l getBytes :例如“中”.getBytes(“字符集”),根据指定的字符集进行编码
l String(bytes[],”字符集”):根据自定的字符集对字节数组进行解码
为什么会出现乱码问题
浏览器和服务器通过网络相连,浏览器请求编码成字节流在网络上传输,应用服务器接收到浏览器发送过来的字节流后通过相应的字符集再解码为字符串,如果浏览器和服务器端使用了不同的字符集或者不兼容的字符集就会导致乱码问题,例如,浏览器将“中”按照UTF-8编码为字节E4 B8 AD,在网络上传输,应用服务器接收到字节后按照GBK进行解码,那么前两个字节首先被解码为“涓”了,这只是个简单的过程说明,实际的过程比这要复杂。
因此要搞清web的编码问题,很有必要先弄清请求的过程和过程中的编码和解码。web是请求响应模式,用户操作浏览器,例如点击一个按钮提交表单,或者点击一个超链接,这时浏览器就会向应用服务器发送请求,servlet容器接受到请求后,根据web.xml的设置调用相应的应用程序,应用程序根据发送的请求进行一定的逻辑处理后返回给浏览器一段html代码,浏览器根据html解析并展现给用户,这就是一次请求应答的过程,下面对各部分作更加详细的介绍:
1. 浏览器向应用服务器发送请求
浏览器向应用服务器发送请求一般通过三种方式:1.提交表单,2.超链接,3.Ajax;
1)表单提交
表单提交又分为post和get两种方法,
采用post方法时浏览器会将表单中的字符串,采用页面的字符集编码为字节流发送到服务器,
采用get方法时,浏览器首先会将表单中的值通过页面的字符集进行URI编码后拼接到action的URL后面发送到应用服务器,例如:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>test</title>
</head>
<body>
<form action=http://www.google.com>
<input type=text name=test value="中" />
<input type=submit />
</form>
</body>
</html>
在点击提交的时候,URL为 www.google.com.hk/?test=%E4%B8%AD,可以看出“中”字被编码为%E4%B8%AD,因为当前页面的字符集为UTF-8,所以在进行get表单提交时将按照UTF-8字符集进行URI编码。
2)超链接
在超链接中一般会传递参数,有时候也会传递中文,如这段代码:<a href="http://www.google.com/?test=中">link</a>,
浏览器最终发送给服务器的都是asc字符,其中的“中”不属于asc字符集,因此也会对其进行URI编码的,但是不同的浏览器采用的字符集却不一样,如上面的这个超链接片段,在windows7中,不论页面的content="text/html; charset=utf-8"还是content="text/html; charset=GBK"IE8发送的都是www.google.com.hk/?test=%D6%D0,可以看出这是GBK的URI编码,IE8对超链接中的URI编码与页面的编码无关,与系统的默认编码有关;而在windosx xp中,IE8发送的是页面编码采用的字符集进行的URI编码,如果页面编码为GBK,IE6发送的为GBK的页面编码,如果页面编码为UTF-8则只发送UTF-8的URI编码的前两个字节;在其他的浏览器中,如Firefox和chrome,其URI编码采用的是页面的编码。
可以看出,直接在URL中带中文,IE的不同版本在不同的操作系统中进行URI编码的结果可能不一样,chrome和firefox使用编码和表单的get方式的编码一致,因此,直接在链接中写非asc字符是很危险的,因为字符的编码方式和客户端的环境有关。所以为了避免浏览器进行不确定的URI编码,需要在程序中将中文进行URI编码后在放到URL中,JavaScript提供了encodeURI()函数,它提供的是UTF-8的URI编码,也可以通过java.net.URLEncoder.encode(str,"字符集")进行编码
3)ajax
ajax可以指定get方式或者post方式,情况和上面说的类似
2. 应用服务器获取参数
在servlet中一般通过request.getParameter()来获得浏览器发送过来的参数,需要注意的是,服务器Servlet的最底层接受到的是InputStream,也就是字节流,request.getParameter()返回的是一个字符串,因此在getParameter()方法的内部存在解码的过程,而解码所采用的字符集根据应用服务器和操作系统的不同有可能不同,ServletRequest接口提供了一个方法:setCharacterEncoding()来设置getParameter解码的字符集,这个方法必需在getParameter之前调用,通过查看tomcate的源代码发现getParameter在第一次调用时会去初始化一个map的对象,map中存储的就是参数名和参数值,这些值就是根据设置的字符集进行解码的,一旦这些对象解码完毕,下次调用就直接从map中取值,而不需要重新去解码了,所以setCharacterEncoding必需在getParameter之前调用才有作用,也有人说这个方法只对post传递参数有效,而对get方法传递的参数无效,对tomcat5确实是这样的,但是对Websphere和apsuic,setCharacterEncoding对post和get同样有效。
从上面的表格可以看出,Websphere6.1,apusic5.1应用服务器的get和post方法其getParameter解码所用的字符集是setCharacterEncoding所指定的字符集,tomcat5的post方法使用的是setCharacterEncoding,但是get方法却不是。在回过头看看这几个试验的过程,浏览器使用post方法时将会采用页面的字符集进行编码成字节流发送到服务器,服务器接收到字节流后根据setCharacterEncoding设定的字符集进行解码,获得字符串,
也就是说,如果使用post方法提交,只要保证“页面的编码的字符集=setCharacterEncoding设置的字符集”那么getParameter获得的值就是正确的,get和超链接的方式类似,
表单使用get提交时,会根据页面的编码进行encodeURI,超链接的方式程序可以根据指定的字符集进行URI编码,
两种方式的共同点是浏览器都会进行URI编码,在Websphere中,get和超链接的方式只要“URI编码的字符集=setCharacterEncoding的字符集”,那么getParameter的结果就是正确的,而使用get提交表单时其“URI编码的字符集=页面编码的字符集”,超链接的URI编码的字符集在上面说过,chrome和Firefox浏览器中URI编码的字符集=页面编码的字符集,但是IE却不是,没有规律。
tomcat5.5中getParameter获取get方法或超链接传过来的参数时默认会用ISO8859-1进行解码,例如浏览器发送UTF-8的编码的请求,tomcat5.5的getParameter使用ISO8859-1解码,这时的结果是错的,如果要获得正确的值,需要在tomcat5.5的getParameter的时候采用UTF-8进行解码,通过设置URIEncoding="UTF-8"或者useBodyEncodingForURI="true",就能让tomcat在的getParameter时采用UTF-8解码(useBodyEncodingForURI="true"表示解码的字符集采用与页面编码相同的字符集),如果不通过配置要并且需要获得正确的值,则需要程序进行转码,因为getParameter是通过ISO8859-1解码的,所有先通过getParameter().getBytes("ISO8859-1")编码成原来的字节数组,然后使用UTF-8字符集解码为字符串:new String(getParameter().getBytes("ISO8859-1"),"UTF-8")
3. 设置浏览器的页面编码
服务器向浏览器发送的也是经过编码成字节流在网络上传输,浏览器接收到字节流之后使用指定的字符集解码成字符串再进行展现,如果这两个环节的字符集不一致也会导致乱码的问题,
例如静态HTML文件或jsp中都是以UTF-8保存的,则需要告诉浏览器用UTF-8来进行解码,
如果是jsp可以通过<%@ page contentType="text/html; charset=UTF-8" language="java" %>来进行设置,
静态文件可以通过 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 进行设置,
如果在servlet中直接进行输出,可以通过response.setCharacterEncoding("UTF-8"),setContentType("text/html;charset=UTF-8"),setHeader("Content-Type","text/html;charset=UTF-8")进行设置,
这些操作都相当于在response的头部增加"Content-Type:text/html;charset=UTF-8"信息,
header中的编码信息的优先级要高于html的meta标签,也就是说如果serlvet中设置了setContentType("text/html;charset=UTF-8"),jsp设置了<meta http-equiv="Content-Type" content="text/html; charset=GBK"/>则浏览器会按照UTF-8字符集进行解码,
分享到:
相关推荐
【标题】"ktv前台项目源码"涉及的是一个针对KTV场所的管理系统的前端源代码,这通常是一个用户界面,用于接待、预订、管理房间和处理顾客订单等功能。在这个项目中,源代码是实现这些功能的核心部分,它包含了一系列...
4. 代码质量检查工具:ESLint和JSLint可帮助发现潜在的性能问题和编码规范问题。 三、Ajax性能提升 1. 利用HTTP缓存:设置合适的HTTP头如`Cache-Control`和`ETag`,使浏览器能缓存Ajax请求的响应。 2. 合理使用...
这些事件处理函数可以用来触发特定的用户行为,比如导航、表单验证或数据提交。 2. **DOM操作**:前端开发者经常需要操作文档对象模型(DOM),`common.js` 可能封装了获取元素、添加元素、删除元素或更新元素属性...
- **前台与数据库之间的接口**:设计一个公共类来处理数据库连接和操作。 #### 八、模块设计 通过提供的use case图可以看出,系统设计了多个不同的功能模块,包括但不限于用户认证、发帖、回帖等功能。每个模块之间...
通过这种方式,当我们在GBK编码的页面上使用$.ajax()进行数据提交时,jQuery内部调用的jQuery.param方法不会对数据进行编码处理,这样数据就可以以GBK编码的形式直接传输到服务器端。由于服务器端和页面编码一致,...
综上所述,解决AJAX提交中文乱码的问题主要涉及客户端和服务端两个方面的编码处理。在客户端通过`URLEncoder`进行编码,并确保Content-Type正确设置;在服务端则通过`URLDecoder`进行解码,并对Servlet容器及程序中...
这种方法相比于传统的表单提交,更加灵活且易于使用,能够实现更为复杂的前后端交互。$.post函数的基本语法如下: ```javascript $.post(url, data, success, dataType); ``` - `url`:指定要发送POST请求的服务器...
这样,每个页面都可以继承这些通用元素,减少重复编码。例如,可以创建一个包含导航栏、页眉和页脚的主布局文件,然后在每个前端和后台页面中通过`include`语句插入这个布局文件。这种方法使得全局样式和脚本的管理...
2. 订单处理:接收前端提交的订单信息,进行订单状态跟踪,包括待支付、已支付、发货、已完成等状态。 3. 会员管理:后台可查看所有会员信息,进行会员等级设置、积分管理、优惠券发放等操作。 4. 数据分析:收集...
解决办法 1、在后台获取时采用 ... 此处 gbk 是前台页面编码方式 3、如果上述方法还不能解决问题 在前台处理汉字 java.net.URLEncoder.ecode("中文","GBK");//前面是要处理的中文字符 eg: win
从最初的前台纸质资料提交,到2017年的网上业务大厅,再到如今的中国编码APP,商品条码服务已逐步实现全程电子化,为客户提供更为便捷的服务体验。 在早期,商品条码业务的办理需要客户亲自前往前台,提交纸质资料...
- 如果情况紧急,需要手动更新环境,规范中给出了针对JSP页面、前台类(Front)和后台类(service)的更新步骤。这涉及替换服务器上的文件或重新打包JAR文件。 5. **测试与记录**: - 测试人员在验证代码无误后,需做...
3. 表单验证:showNote()函数中涉及到表单提交前的验证逻辑,具体表现为onsubmit事件触发showNote()函数,以及checkMax(obj)函数的调用,这些操作涉及到了前端用户输入数据的验证机制。 4. HTML表单元素:表单内...
例如,当用户输入不合法时,可以即时显示错误信息,而不需要等到用户提交表单后才显示。 8. **库和框架支持**: 当然,现代前端开发中,有许多库和框架如jQuery、React、Vue等提供了现成的验证插件和组件,可以...
在5Ucms留言插件中采用UTF-8编码,意味着无论用户使用何种语言进行留言,都能够被正确地显示和处理,增强了插件的国际化能力。 该插件已移除了前台显示留言的功能,这意味着用户无法直接在网站页面上看到其他用户的...
在这款系统中,前台通常面向用户,提供直观的交互界面,而后台则负责数据处理、权限管理以及系统维护等核心功能。 1. **订单管理**: - 订单创建:用户可以在前端提交新订单,系统将记录订单的详细信息,如产品/...
- 这个毕设项目作为课程设计的一部分,学生可能需要完成需求分析、系统设计、编码、测试以及文档编写等环节,全面锻炼了软件开发的全过程。 10. **学习资源**: - 对于其他学习者,这个项目可以作为一个实践案例...
项目通常遵循需求分析、设计、编码、测试、部署的步骤。在开发过程中,需要考虑用户体验、安全性、性能优化等方面,同时,前后端之间通过API进行通信,实现数据交换。 6. 维护与升级: 一个成熟的企业黄页网站...
2. **前端编码处理**:对于前端页面,无论是使用GET还是POST方式发送请求,都应对参数进行适当的编码处理。 3. **服务器端解码处理**:服务器端接收到请求后,需先对参数进行解码,再进行后续处理。 4. **响应编码...
4. **处理数据提交**:在后端(如C#的ASP.NET MVC或Web Forms),设置接收和处理富文本数据的控制器方法。由于HTML代码可能包含XSS(跨站脚本攻击)风险,需要进行安全过滤或HTML编码以防止用户攻击。 5. **显示...