[转]有关Web应用服务器的显示编码问题

 

有关Web应用服务器的显示编码问题

刘睿
2005年7月

最近和一个软件开发商的工程师聊了一下Web应用服务器的显示编码问题,于是感觉不少人虽然玩了多年的软件,对这个问题还是云里雾里,很少有人能清晰地说明这一问题,网上也基本没有相关的精辟的文章。所以在这里就简单介绍一下,帮初学者入入门。需要指出的是,不同的Web应用服务器很可能采用不同的方式。这里仅仅以IBM WebSphere为例,其它服务器比如Tomcat和WebLogic,以后有机会再说吧。

1. 浏览器的设置:

1.1 浏览器的语言相关设置:
  IE浏览器会把自己支持的语言(在IE浏览器可以设置该语言选项)通过HTTP请求头Accept-Language,并上传给Web服务器供参考。但服务器一般都忽略HTTP请求头Accept-Language,我知道有些应用程序就通过读这个HTTP请求头(Accept-Language)来实现一定的国际化。(注:WebSphere对Servlet的扩展属性autoRequestEncoding和autoResponseEncoding就是利用这个“Accept-Language”。)
  另外,如果HTML没有定义“<META http-equiv="Content-Type"...>”,且服务器也没有返回HTTP头Content-Type和Content-Language,就以自己首选的语言解释HTML。(此时就很可能出现服务器返回的中文乱码)

1.2 浏览器缓存:
  浏览器重复访问同一网页时,发送的HTTP头(last-modified),服务器可以返回HTTP Code 304 - Not Modified,于是从本地缓存取网页。
  有时候语言环境变了,浏览器的显示还没变,就可能是缓存的问题。
  当然一般浏览器都有主动选择变换语言的功能,实际上是用不同的语言解释显示的HTML。

2. 浏览器如何理解HTTP返回内容的编码:
  首先,看服务器返回的HTTP头Content-Type;
  其次,看HTML中的“<META http-equiv="Content-Type"...>”;
  最后,看服务器返回的HTTP头Content-Language,注意Content-Language与服务器默认的文件编码一致。

2.1 WebSphere服务器返回HTML时,其返回数据的HTTP头Content-Type不包含字符集。所以说:其HTML数据的编码必须和“<META http-equiv="Content-Type"...>”声明一致,这样才能让浏览器有正确的理解。如果你在WebSphere Studio或者Eclipse中开发HTML,这种一致性是由该工具保证的。
  服务器在发送HTML时,服务器不会做任何编码转换。如果有必要,浏览器在显示时自己进行转换(对用户透明)。

2.2 WebSphere服务器调用Servlet或JSP时,其返回数据的HTTP头Content-Type肯定包含字符集(默认是ISO-8859-1),所以HTML中的“<META http-equiv="Content-Type"...>”声明必然被忽略。
  那么,这个HTTP头Content-Type是怎么决定的呢?在Servlet,使用ServletResponse接口的setContentType;在JSP中,参见声明“<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030" %>”中的contentType部分。(注意JSP声明中的pageEncoding部分,指的是JSP源文件(对比Java源文件)的编码。对WebSphere来说,JSP源文件的默认编码可以由JVM命令行参数-Ddefault.client.encoding=...来设置。)
所以说:其Servlet和JSP的数据的编码必须与其相应的声明一致,这样才能让浏览器有正确的理解。如果你在WebSphere Studio或者Eclipse中开发JSP,这种一致性是由该工具保证的。

3. 服务器如何理解HTTP请求参数的编码:
  服务器得到客户机的GET或POST请求时,一般都会有一些参数。这些参数很可能是从浏览器输入的,也可能是带在HTML中的,那么服务器如何理解这些参数的编码呢?
  这个问题实际上并没有得到圆满的解决。一般服务器都会忽略IE浏览器的语言选项决定的HTTP请求头(Accept-Language),所以就不知道浏览器输入的数据的编码。于是只能使用ServletRequest接口的setCharacterEncoding方法来设置。对WebSphere来说,还可以使用JVM命令行参数-Ddefault.client.encoding=...来设置一个默认值。
  值得一提的是,如果没有任何设置,WebSphere就按照ISO-8859-1来解释,也可以通过一个简单的校正的方法得到原始的参数值(比如:new String( paramValues[0].getBytes("8859_1"), "GBK" ))。其它的Web应用服务器不一定采取相同的办法。比如WebLogic8就默认使用UTF-8来解释参数的编码,而且不支持简单的校正。
  如果你愿意使用WebSphere扩展的非标准Servlet属性autoRequestEncoding和autoResponseEncoding,就能利用HTTP请求头(Accept-Language)来决定HTTP请求参数的编码。

 

原文:http://www.lrsolution.com/resource.html

 

你可能感兴趣的:(Web,编码)