原标题:link标签和script标签跑到body下面,网页顶部有空白,出现“锘匡豢”乱码,UTF-8 BOM,EF BB BF

来自:http://tunps.com/link-and-script-goes-under-body-tag

最近在做一个简单的记账系统,用php+mysql。在要完工的时候发现了一个问题,研究了2天的时间才有了答案。

以下是页首的裁图:

页面的头部有空白区域。有的人可能怀疑是css的margin,padding,border没有重置为0造成的。其实不然,我已经将这几个属性重置为0。

而且在firebug下面查看HTML代码会发现link标签和script表情跑到body下面:

并且body标签下面和link标签之间有空行。

我自诩的查看我的模板文件是没有任何问题的,想了很久最后实在是没辙了,跑到Stackoverflow高手云集的地方去提问

有个人提出了是页面中存在stray text。

You've got some stray text content inside the , before the tag. The browser sees the text and decides this means you're starting the main document body but have forgotten to include the tag.

This is actually valid—if inadvisable—in HTML4: the end-tag and start-tag are both optional. This is how you can have just Hello! as a valid HTML document. But it's not permissible in XHTML, so if you validate your document you should get a “character data is not allowed here” error at the point the stray text occurs.

The browser then parses the rest of the document as body content, putting the inside the body (which is not valid, but which is nonetheless commonplace). It ignores the real when that comes along because it already has a body.

If you can't see the stray text, perhaps it's an invisible character like U+00A0 No-break space or—most likely for Chinese documents—U+3000 Ideographic space , which you may get when you press space in some input method modes. These characters won't be visible, but they're not ‘ignorable whitespace’ like a normal U+0020 Space or newline, so they trigger ‘text content’ processing and force the .

就是说页面存在浏览器不能忽略的空白,比如U+0020活U+3000之类的。

我的php脚本全部使用的是utf-8编码,html页面的charset也就是utf-8,我强制让浏览器把页面用其他编码来解析,比如GB2312,然后出现了如下图的情况:

空白的部分出现了乱码,而且内容都是“锘匡豢”,这下子更是把我搞糊涂了。我按照SO上面bobince兄的建议,把模板页传到W3C markup validator上面去检查,得出来如下结论:

大概意思是说,UTF-8中的BOM编码在一些编辑器或者是浏览器中支持不好,可能会出现问题。

然后网上搜索了关于Byte Order Mark的信息:

在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little- Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

Windows就是使用BOM来标记文本文件的编码方式的。

然后我用UltraEdit的16进制编辑模式查看代码,都是EF BB BF开头的,说明都是带BOM的。我手动的将所有文件转成UTF-8 without BOM。页面终于正常了。link,script标签乖乖的跑到head下面,网页顶部空白消失。oh yeah。这就是搞了2天的答案。

最后我在网上随便下载了知名php程序的utf-8版,发现都是UTF-8 without BOM的。

那么我们继续回头看看出现问题的现象就有答案了。“锘匡豢”在页面头部出现多次的原因是首页处理文件index.php require_once了多个类和库文件,而那些库和类文件都是用的带BOM的UTF-8,所有PHP无法识别,直接将EF BB BF输出,在charset="utf-8"的页面中是空白,在GB2312的页面中的输出的就是一个稀有汉字。不信可以查锘匡豢这几个字的GB2312代码是多少:

UTF-8编码是变长的,1—6个字节。其中汉字编码,是3个或4个字节。而恰好EF BB BF多次出现,两个EF BB BF组成EFBB BFEF BBBF ,而EFBB BFEF BBBF就是“锘匡豢”的UTF-8编码。这也是很多网站页面顶部出现“锘”加一个方框。

看来得找个时间恶补编码知识了。

相关阅读:

[1] 字节顺序标记.http://zh.wikipedia.org/zh-cn/%E4%BD%8D%E5%85%83%E7%B5%84%E9%A0%86%E5%BA%8F%E8%A8%98%E8%99%9F.2013-06-19

[2]PHP源码编码与转换:搞定首行为空和“锘匡豢”.http://chensd.com/2011-09/php-source-convert-gbk-big5-to-utf8.html.2013-06-19

[3]【转】PHP源码编码与转换:搞定首行为空和“锘匡豢”.http://www.cnblogs.com/fzzl/archive/2012/11/20/2780015.html.2013-06-19

UTF-8 BOM(EF BB BF)的更多相关文章

  1. 关于bom ef+bb+bf的问题

    今天在商品详细页头部出现了一行空白,各种尝试无果,最后怀疑是不是bom头的问题,经过断点跟踪调试逐步缩小范围,果然最后发现是一个语言包文件的开头有 ef bb bf样式的字节,用ultraedit另存 ...

  2. UTF-8文件的Unicode签名BOM(Byte Order Mark)问题记录(EF BB BF)

    背景 楼主测试的批量发送信息功能上线之后,后台发现存在少量的ERROR日志,日志内容为手机号码格式不正确. 此前测试过程中没有出现过此类问题,从运营人员拿到的发送列表的TXT,号码是符合规则的,且格式 ...

  3. jsp %EF%BB%BF

    utf-8 bom 问题,页面中存在不可忽略的空白,去掉即可 很微妙的一个空格,不易发现

  4. Unicode 与 Unicode Transformation Format(UTF,UTF-8 / UTF-16 / UTF-32)

    ASCII(American Standard Code for Information Interchange):早期它使用7 bits来表示一个字符,总共表示27 = 128个字符:后来扩展到8 ...

  5. 常见编码和编码头BOM

    ANSI(American National Standards Institute,美国国家标准学会)ANSI编码标准是指所有从基本ASCII码基础上发展起来的编码标准,比如扩展的ASCII码(12 ...

  6. 文字编码ASCII,GB2312,GBK,GB18030,UNICODE,UCS,UTF的解析

    众所周知,一个文字从输入到显示到存储是有一个固定过程的,其过程为:输入码(根据输入法不同而不同)→机内码(根据语言环境不同而不同,不同的系统语言编码也不一样)→字型码(根据不同的字体而不同)→存储码( ...

  7. 简单聊下Unicode和UTF-8

    今晚听同事分享提到这个,简单总结下. ## Unicode字符集 Unicode的出现是因为ASCII等其他编码码不够用了,比如ASCII是英语为母语的人发明的,只要一个字节8位就能够表示26个英文字 ...

  8. Java 字符编码(一)Unicode 字符编码

    Java 字符编码(一)Unicode 字符编码 Unicode(http://www.unicode.org/versions/#TUS_Latest_Version) 是一个编码方案,说白了希望给 ...

  9. Unicode 与 Unicode Transformation Format(UTF-8 / UTF-16 / UTF-32)

    ASCII(American Standard Code for Information Interchange):早期它使用7 bits来表示一个字符,总共表示27 = 128个字符:后来扩展到8 ...

随机推荐

  1. Maven安装testNG

    1.Maven安装testNG (1)打开网站:http://testng.org/doc/maven.html (2)复制如下代码,粘贴到项目的pom.xml文件: 1 <dependency ...

  2. 骑士周游问题 --- 递归解法 --- java代码

    骑士游历: 定义了向量的数组M,行数组X,列数组Y, 棋盘plane,计数器count,走动步数step 需要注意的是,递归函数的进入前的验证,原先的想法是传入来时的方向参数,可是这样的想法被实践否定 ...

  3. OpenGl从零开始之坐标变换(下)

    这节主要来理解投影变换和视口变换的使用. 1.正射投影:glOrtho 函数原型: void glOrtho(GLdouble left,GLdouble right,GLdouble bottom, ...

  4. mysql 经典题目

    题目1:实现如下效果 CREATE TABLE IF NOT EXISTS tb_amount( `Id` INT NOT NULL AUTO_INCREMENT, `), `), `Amount` ...

  5. 最小高度的BST

    加深对BST的构建过程及递归思想的理解. /***************************************************** * \file MinimalBST.cpp * ...

  6. 精美&创意的WordPress新发主题集合

    今天我整理了一些精美&创意的WordPress新发主题,它们基本上都融合了最新的设计理念,从简约到响应式,应有尽有. Engo – Smart & Minimal WordPress ...

  7. 【Visual Studio2010】创建XAML分析插件

    最近项目[Silverlight]中的需要实现国际化,需要对所有控件进行一个处理.由于使用了Telerik的控件,只需要去掉原有的Label或者Header属性,然后添加一个资源Key即可.但是在项目 ...

  8. C++视频课程小结(3)

    C++远征之封装篇(上) 章节介绍: 每章小结: 第一章:课程介绍. 按照惯例是章节的总介绍,内容明显多了很多(为了做作业我还要赶进度的说),主要说了:类和对象是本章的主角,然后还有很多配角,像数据成 ...

  9. HDU 4284Travel(状压DP)

    HDU 4284    Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1 ...

  10. Linux下Hadoop集群环境的安装配置

    1)安装Ubuntu或其他Linux系统: a)为减少错误,集群中的主机最好安装同一版本的Linux系统,我的是Ubuntu12.04. b)每个主机的登陆用户名也最好都一样,比如都是hadoop,不 ...