在web开发中遇到最头痛的问题莫过于乱码的问题,乱码的问题看似简单,其实是很复杂的,涉及的知识面太广,操作系统的编码、文件编码、服务器返回的数据所使用的编码、服务器告诉浏览器返回数据所使用的编码、浏览器展示页面时所使用的编码等等,要真正明白各种乱码的原因,你甚至还要理解各种编码的编码原理,像UTF-8、UTF-16、GBK等。下面由一个简单的程序来引出主题的探讨:
@Controller
@RequestMapping("/test")
public class TestController{
@RequestMapping("sayhi")
public void sayHi(HttpServletRequest req,HttpServletResponse res){
res.setCharacterEncoding("UTF-8");
res.getWriter.write("世界,我来了");
}
}
上面是spring mvc一个简单的Controller向客户端输出一段中文字符串,下面是浏览器(firefox4.0.1)的输出
从服务器返回的数据长度可知道,数据的确是按照UTF-8编码的,但响应头并没有编码信息,即浏览器并不知道服务器返回的数据编码方式,由Accept-Charset知,浏览器展示页面用的UTF-8编码,那么浏览器怎么讲服务器的数据展示出来呢?
浏览器要展示必须将服务器端的数据转换为UTF-8编码,但浏览器并不知道服务器数据的编码方式如何转换呢?当浏览器不知道服务器返回数据的编码方式时,就把它的编码方式当做和操作系统的字符集编码一样。因为我使用的是中文操作系统,所以浏览器展示页面时,就将服务器返回的数据以gb2312的方式转换为UTF-8的编码。但上图中服务器返回的数据实际是UTF-8编码的,有9个字节,被当做GB2312来处理当然会有问题。
上面的根本问题就在于浏览器把服务器UTF-8编码的数据当做GB2312编码来处理,那如何让浏览器知道服务器返回数据的编码方式呢?很简单,在响应头中设置编码方式就行了,像下面这样:
res.setContentType("text/plain;charset=UTF-16")
res.getWriter.write("世界,我来了")
或
res.setCharacterEncoding("UTF-16")
res.setContentType("text/plain")
res.getWriter.write("世界,我来了")
浏览器的输出:
你可能会觉得奇怪,为什么服务器的数据编码是UTF-16(content-type中指定的,数据长度也是14),浏览器展示页面用的UTF-8的编码(accept-charset中指定的),而没有出现乱码?这是因为浏览器知道服务器返回数据的编码方式是UTF-16后,它会就数据从UTF-16的方式转换为UTF-8编码,数据就能正确展示出来。所以charset中不管你指定什么编码(前提是这种编码支持中文,像ISO8859就不支持中文。如果指定为ISO8859编码,就会有数据丢失,就不能转换accept-charset指定的编码),浏览器都能正确展示。
到这里,你应该似乎明白了数据在服务器和浏览器之间的编码转换过程。那我们再看下面的例子:
res.setCharacterEncoding("UTF-16")
res.getWriter.write("世界,我来了")
浏览器输出:
上面这幅图除了响应头的数据长度(由数据长度可知服务器端数据的编码方式确实是UTF-16),响应和请求头其他的信息和第一幅图一样,那浏览器为什么能正确显示数据呢?这是因为由于没有指定服务器端返回数据的编码方式(即conent-type中没有指定charset),浏览器就把服务器返回的数据当做gb2312编码来转换为UTF-8编码来展示出来,而原来是UTF-16编码的数据当做gb2312来处理时没有问题的,具体原因大家可以去看gb2312和UTF-18的编码原理,所以浏览器能正确显示数据。
这案例中有以下几点要注意:
1、若只调用setCharacterEncoding(),则只是高告诉服务器返回的数据的编码方式,并没有告诉浏览器数据的编码方式(即不会产生content-type头字段)。
2、只有在调用setContentType()时指定具体的mime-type才会产生conent-type头字段,若没有调用setCharacterEncoding(),也没有指定charset,则会使用charset则会被设置为ISO8859-1;调用了setCharacterEncoding(),则使用该方法指定的字符集
3、setContentType()中设置的charset会覆盖setCharacterEncoding()方法。
相关推荐
### Java字符串编码转换详解 #### 一、Java 字符串编码转换基础 在Java中,字符串的处理是非常常见的操作之一,而字符编码是确保数据正确显示的关键因素。本篇文章将重点介绍Java中字符串编码的转换方法及其在Web...
综上所述,JsonView插件是开发者和数据分析人员的得力助手,它简化了JSON数据的查看和理解,提升了工作效率。通过安装jsonview-0.0.32.2.crx文件,用户可以将这个功能强大的插件添加到自己的浏览器中,享受便捷的...
3. **网络传输中的编码问题**:在网络环境中,如Web应用程序中,客户端发送的数据和服务器端接收的数据可能存在编码不一致的情况,尤其是在处理HTTP请求时,若没有明确指定字符集,浏览器通常会默认使用UTF-8编码...
`mb_convert_encoding`函数就是这样一个工具,它允许开发人员在不同的字符编码之间进行转换,从而确保数据的正确显示和处理。本文将深入探讨这个函数的用法和应用场景。 `mb_convert_encoding`函数的基本语法如下:...
针对此问题,我们可以通过检测用户的浏览器类型,并根据不同的浏览器类型来动态地对文件名进行编码转换,以此确保所有类型的浏览器都能够正确解析文件名。 #### 三、实现步骤 1. **获取用户代理信息**:通过`...
根据提供的文件信息,本文将详细解析HTTP下载过程中对包含中文路径进行UTF-8编码转换的...在实际开发中,开发者需要根据具体需求选择合适的编码方案,并注意编码转换过程中的细节处理,以确保数据的正确性和完整性。
2. **获取用户代理字符串**:使用`navigator.userAgent`属性获取浏览器发送给服务器的用户代理字符串,并将其转换为小写形式。 3. **条件判断**: - **IE浏览器**:通过`ActiveXObject`的存在性来判断是否为IE浏览...
而AJAX的参数详解涉及到了在使用AJAX进行数据交互时各个参数的意义及使用方法,以及如何处理返回状态和状态函数来获取数据。 首先,来看看url参数,这是AJAX请求中的必填项,它指定了请求发送的目标地址。url可以是...
- **输入验证和编码**:对用户提交的数据进行严格的验证和转义处理,避免恶意内容被注入到网站中。 综上所述,了解浏览器的工作原理和技术细节对于防范XSS蠕虫攻击至关重要。开发者和安全专家应当密切关注最新的...
5. HTTP(超文本传输协议):HTTP是万维网的核心,负责浏览器与服务器之间的通信。书中会涵盖HTTP请求方法、状态码、首部字段、cookies以及持久连接等关键概念。 此外,卷3还涵盖了其他协议,如TFTP(简单文件传输...
- 对于Web应用,确保Web服务器和应用程序服务器配置正确,如设置Tomcat的`URIEncoding`属性为正确的编码。 - 对于文件读写,使用`BufferedReader`和`BufferedWriter`,通过`new InputStreamReader()`和`new ...
- **手动转换**:在服务器端接收参数时,使用`new String(request.getParameter("something").getBytes("ISO-8859-1"),"utf-8")`进行编码转换。 - **设置请求编码**:在请求页面开始处调用`request.setCharacter...
HTTP(超文本传输协议)是互联网上应用最为广泛的一种网络协议,它定义了客户端(通常是浏览器)和服务器之间数据交换的格式和行为。在本文中,我们将深入探讨HTTP的工作原理,以及它如何在浏览器客户端与服务器之间...
由于HTTP协议本身是基于ASCII编码的,所以在传输非ASCII字符(如中文)时,需要进行编码转换处理,确保数据能够在不同编码环境之间正确传递。 #### 二、request.setCharacterEncoding()方法详解 `request.set...
5. **与服务器端的交互**:FCKeditor 可以通过AJAX技术与服务器进行数据交互,实现实时保存和预览等功能。 **二、FCKeditor 在JSP中的应用** 在JSP页面上使用FCKeditor,通常涉及以下几个步骤: 1. **引入库文件*...
对于单个网页,可以使用在线的编码转换工具,如“在线编码转换器”,输入乱码内容后选择正确的源编码和目标编码,进行转换查看是否能够解决问题。 ### 三、总结 Linux下网页乱码的解决方案涉及多个方面,包括...
7. **过滤器和监听器**:讲解Filter接口和Listener接口,以及如何实现URL过滤、字符编码转换、监听器事件处理等。 8. **部署与发布**:如何将Java Web应用打包成WAR文件,部署到Tomcat服务器上,以及理解WEB-INF...
- **服务器端处理**:在服务器端使用正确的编码方式读取和写入数据。例如,使用`Encoding.UTF8.GetString(bytes)`将字节数组转换为字符串。 - **数据库交互**:确保数据库连接字符串中指定了正确的字符集,如`...
3. **bg.js**:后台脚本文件,插件的核心代码,负责监听用户的操作并执行相应的编码转换功能。 4. **manifest.json**:这是Chrome扩展的配置文件,包含了插件的元数据,如名称、版本、权限等信息。 5. **bin_128sq...