

)昨天帮同事解决的一个问题,GBK的页面(不要问我为什么GBK,因为GBK,所以GBK),引用了Google map的API, 但是由于GoogleMap API返回的js脚本是utf-8的,所以导致在IE下, 浏览器无法正确解析.
这个问题,总的来说,可以用下图描述(原谅我的美术水平):
也就是, 由于服务器中生成的HTML是基于gbk编码的, 并且由于Apache的DefaultCharset(后叙), 所以导致IE会以gbk编码去解析从外部引入的GoogleMap js,那肯定是不能正确解释的.
浏览器判断一个页面的编码有俩个途径, 一种是通过HTTP响应头,
HTTP/1.x 200 OK Date: Sat, 18 Oct 2008 21:53:51 GMT Server: Apache/2.0.52 (Red Hat) X-Powered-By: PHP/5.3.0alpha2 Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=GB2312
注意最后一行, 这个是由HTTP头部指明的页面编码格式.
另外一种就是我们常见的, 也会另很多初学者困惑的meta:
<head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>风雪之隅 </title> </head>
问题就在于,没有一个统一的标准,来指明这俩中方式的优先级, 不同的浏览器有着不同的优先级策略.这也就是为什么,我们在FF下正常浏览的页面,在IE下会乱码的原因.
我之前的文章Apache的Charset设置中已经介绍过了在Apache下设置DefaultCharset以后产生的影响,
这个问题已经遇到过俩次了,就是页面中明确指明了编码是UTF8,但是显示是乱码。
虽然知道解决方法,也知道是Apache的原因,但是一直没有去找其所以然,今天趁机,就研究了一下。
1. 页面没有指定charset , Apache配置defaultcharst gbk , 页面文件编码是utf-8
结果: 乱码,使用wireshark抓包,发现服务器返回的header中指明了:
Content-Type:text/html;charset=GBK结论:当页面没有指明charset的时候,Apache的defaultcharset起作用
2. 页面指定charset为utf-8, Apache配置defaultcharset gbk. 页面文件是utf-8
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <div id="page-header"> 测试Apache DefaultCharset </div> </body> </html>结果还是出现乱码。
结论:当Apache配置了DefaultCharset, 将忽略页面的charset申明。
3 PHP header申明charset为utf8, Apache配置defaultcharst gbk,页面文件编码是utf8
header("Content-Type:text/html; charset=utf-8");结果 : 页面显示正常。
4 Apache设置DefaultCharset off
结果,页面显示正常。
翻阅了下Apache2的手册:
AddDefaultCharset指令 说明当应答内容是text/plain或text/html时,在HTTP应答头中加入的默认字符集 语法AddDefaultCharsetOn|Off|charset 默认值AddDefaultCharsetOff 作用域serverconfig,virtualhost,directory,.htaccess 覆盖项FileInfo 状态核心(C) 模块core 当且仅当应答内容是text/plain或text/html时,此指令将会在HTTP应答头中加入的 默认字符集。理论上这将覆盖在文档体中通过<meta>标 签指定的字符集,但是实际 的行为通常取决于用户浏览器的设置。AddDefaultCharsetOff将会禁用此功能。 AddDefaultCharsetOn将启用Apache内部的默认字符集iso-8859-1。您 也可以指定使用在IANA注册过的字符集名字 中的另外一个charset。 比如说: AddDefaultCharsetutf-8也就是说,当Apache不指定defaultcharset的时候,页面编码由页面自己的meta标签指定。
当Apache指定的时候,将忽略页面中的meta标签指定的编码. 但是容许脚本直接header编码方式给客户端
最后,还有一个问题没有得出结果:
当Apache和页面都没有指定的时候, 又如何?
我在自己的机器上,如果都不指定, 默认还是utf8
在服务器端生成response内容以后, 如果脚本没有显示的调用header发送编码申明,那么Apache就会根据DefaultCharset生成响应HTTP头部的Content-type中的charset字段;
反之如果脚本显示申明了,那么就会按照脚本header申明中的charset设置.
这样到了浏览器端以后, 浏览器就可以根据HTTP头的charset申明来按照特定的编码格式解析获取到的HTML代码,但现在的问题是, 页面是GBK的,但是引用的外部js文件是utf8编码的,这样的情况, 我们可以使用一个script的属性来解决:
<script language='javascript' src='....' charset='utf-8'></script>
Tags: apache charset, charset, default charset, header, meta, 外部js文件, 浏览器编码







Apache
browser
bug
C++
charset
COOKIE
core
c写PHP扩展
debug
encoding
engine
Extension
GET
IE
javascript
js
json
Module
mysql
namespace
nginx
PHP
php5.4
PHP5.4新特性
PHP extension
php原理
PHP应用
PHP扩展
php源码
php源码分析
SAPI
session
utf8
variable
vim
Yaf
Zend/PHP
乱码
作用域
原理
开发php扩展
性能
扩展PHP
扩展开发
正则 GNU C/C++ (3)
Js/CSS (24)
Linux/Unix (15)
MySQL/PostgreSQL (7)
PHP Extension (13)
PHP应用 (139)
PHP源码分析 (73)
转载 (30)
随笔 (68)
WP Cumulus Flash tag cloud by Roy Tanck and Luke Morton requires Flash Player 9 or better.









今天偶尔看到此博文,准备收藏起来
学习了
新闻导读 新闻一页看
http://news1page.com
恩,修改默认的connent charset