寻虫记:BOM头制造的冤案,无故多出空白行
最近在做的一个网站发生了一个很诡异的BUG:
- 使用IE浏览页面时,一切都挺正常;
- 而使用Firefox浏览时,发现某些页面元素之间的距离比预期的要宽很多,HTML元素本身的hight、padding和margin值都很正常,只是元素之间像是增加了一个空行或一个类似于DIV的块级元素;用F12调出开发者工具查看后却没有发现任何多出的HTML元素或多余的代码;
- 再用Chrome进行查看,页面的显示效果和firefox一样,但是用F12查看后,发现确实是增加了多余的一行,表现为增加了一个空白字符串,但是占有一个整行的宽度。如下图中header元素的上下所示:

接下来排查错误:
一开始以为是CSS样式中的:before语句对页面元素有了影响,但是:before仅对body元素进行了设置,仅仅只是增加了一个元素,不会造成如此多的元素的间隔距离都拉开了的效果;且在删除:before语句后浏览,问题依然存在。因此排除了这个可能性。
然后开始仔细的检查(过程很痛苦),发现这些出问题的地方都有一个共同点:因为网站是采用静态化实现,使用了服务器端的静态包含,而每个多余的行都出现在每个包含文件(<!--#include virtual="**.inc" -->)的前面。于是去看包含文件的生成过程,去掉文件生成时头尾可能产生的换行符和空白串。但是更新程序后,重新生成静态文件,问题仍然存在。
后来实在找不到问题所在,只能先放一下去完成其他的功能。但是,这个没有解决的问题,一直萦绕在我的心头,时时都能想起它,时时都在想“为什么呢”?如鲠在喉,无法下咽。总觉得有什么事情没做完一样,做其他的事情时感觉也不踏实。
因为基本确认是包含文件出现了问题,于是集中在文件生成和包含这一块进行排除。在做其他事的时候无意中想到文件编码这一块的事情,于是就想会不会是这个因素的影响。于是上网搜索,发现了如下几篇文章:
1、什么是BOM头
3、XML的BOM
看完后,隐约觉得应该是找到问题所在了;于是看了看自己程序,发现在生成静态文件时,采用了UTF-8编码来设置字节流,同时在保存到文件时也采用了UTF-8编码,代码如下:
File.WriteAllText(Task.FullPath + filename + Task.Extension, content, Encoding.UTF8);
于是决定首先利用UE去除BOM头试试效果:打开某一个静态化后的inc文件,另存为时选择“UTF-8 无 BOM”,能BOM头。如下图:

保存文件后再进行浏览,问题不再出现。从而确定了BOM头在一些浏览器内解析时,会被解析为一个空行或者一个块级元素。在用程序保存文件时,如果指定了文件的编码格式为UTF-8,也会为文件增加BOM头。
因此生成文件时,改为去掉文件保存时指定的UTF-8编码,但字节流仍采用UTF-8编码处理。
content = Encoding.UTF8.GetString(bytes);
File.WriteAllText(Task.FullPath + filename + Task.Extension, content);
同时因为字节流采用UTF-8编码,在html页面里需要指定页面的编码方式,不然会出现乱码:
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
做完以上处理,再次重新生成所有inc文件后,在不同浏览器下刷新查看,发现问题均得到解决。
在确认了BUG的原因并最终解决了问题之后,居然找到了这样一篇文章:关于shtml页面include问题解决方案因为utf-8的BOM头引起的出现一个空行 !!为什么总是在费尽九牛二虎之力解决问题后,才发现这么一篇能精确指导解决问题的方案的文章呢?
另外,推荐一个关于编码方面的文章:由web程序出现乱码开始挖掘(Bom头、字符集与乱码)
做程序开发,确实是知道得越多,知道的就越少。坑太多啊。绝逼的学无止尽。
寻虫记:BOM头制造的冤案,无故多出空白行的更多相关文章
- 编码格式简介:ASCII码、ANSI、GBK、GB2312、GB18030和Unicode、UTF-8,BOM头
编码格式简介:ASCII码.ANSI.GBK.GB2312.GB18030和Unicode.UTF-8,BOM头 二进制: 只有0和1. 十进制.十六进制.八进制: 计算机其实挺笨的,它只认识0101 ...
- 什么是BOM头,BOM头有什么影响,怎么去掉BOM头
什么是bom头? 在utf-8编码文件中BOM在文件头部,占用三个字节,用来标示该文件属于utf-8编码,现在已经有很多软件识别bom头,但是还有些不能识别bom头,比如PHP就不能识别bom头,这也 ...
- 详解BOM头以及去掉BOM头的方法
类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM).它是一串隐藏的字符,用于让记事本等编辑器识别 ...
- PHP 版去bom头
原理: 找出文件前3个字符 如果它们对应的ASCII 值分别是 239,187,191 则判断为bom头,去掉前3个字符. 代码实现如下: $basedir = isset($_GET['dir'] ...
- 捉虫记(四)线程安全导致的HighCpu
一个朋友QQ群里说网站启动后会cpu很高,想要帮忙看一下dump. 1.打开windbg加载dump文件后第一个命令lmf,这个命令显示加载的dll以及路径,这样子可以找个dll来帮忙加载sos,(额 ...
- linux下bom头导致的php调用php接口 返回的json字符串 无法转成 数组,即json字符串无法解码的问题
今天很是郁闷,写了一个php接口,返回的是标准的json字符串,但是调用的php 就是无法json_decode(),返回错误码为4,最后终于找到原因,原来是蒙一个文件中有bom头,最后采用一个命令 ...
- 检测文件是否有BOM 头,并删除BOM头(php)
将下面文件放在网站根目录访问即可,它会遍历当前目录下所有子目录,检测文件是否含有BOM头,并删除BOM头 <?php //remove the utf-8 boms //by magicbug ...
- UTF-8 BOM头
BOM是什么 Unicode的学名是"Universal Multiple-Octet Coded Character Set",简称为UCS.UCS可以看作是"Unic ...
- linux下查找包含BOM头的文件和清除BOM头命令
查找包含BOM头的文件,命令如下: grep -r -I -l $'^\xEF\xBB\xBF' ./ 这条命令会查找当前目录及子目录下所有包含BOM头的文件,并把文件名在屏幕上输出. 但 ...
随机推荐
- SimpleDateFormat非线程安全
文章列表 1)SimpleDateFormat的线程安全问题与解决方案 2)深入理解Java:SimpleDateFormat安全的时间格式化
- C#脚本引擎 CS-Script 之(一)——初识
最近在做新产品,这个产品需要满足不同项目对于系统的定制性数据处理需求,比如有的要统计一段时间内某开关打开关闭了多少次,有的要统计一段时间内空调的使用率,有的希望根据温度来控制空调的开还是关,有的则是希 ...
- JAVA中获取当前系统时间
一. 获取当前系统时间和日期并格式化输出: import java.util.Date;import java.text.SimpleDateFormat; public class NowStrin ...
- [CareerCup] 6.3 Water Jug 水罐问题
6.3 You have a five-quart jug, a three-quart jug, and an unlimited supply of water (but no measuring ...
- JS判断输入是否为整数和数字的正则表达式
"^\\d+$" //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$" //正整数 "^((-\\d+)|(0+))$" ...
- 嵌入式Linux利用Wifi搭建无线服务器(物联网实践之无线网关)
在 http://www.cnblogs.com/heat-man/p/4564539.html中,在嵌入式Linux开发板上我们从最底层实现了一个智能家居的远程控制系统,然而采取的是用网线连接到交换 ...
- Linux 容器的使用
Linux 容器的使用 Linux 容器在 v2.6.29版本之后就加入到内核之中了, 之前虽然也听说过, 但一直没有太留心, 一直使用 KVM 来创建虚拟机. 直至最近 Docker 大出风头, 才 ...
- 编写高质量代码改善C#程序的157个建议[匿名类型、Lambda、延迟求值和主动求值]
前言 从.NET3.0开始,C#开始一直支持一个新特性:匿名类型.匿名类型由var.赋值运算符和一个非空初始值(或以new开头的初始化项)组成.匿名类型有如下基本特性: 1.既支持简单类型也支持复杂类 ...
- Linq之IQueryable接口与IEnumberable区别
IEnumerable接口 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代.也就是说:实现了此接口的object,就可以直接使用foreach遍历此object: IEnumerable 包含 ...
- 传智168期JavaEE就业班 day02-css
* 课程回顾: * HTML语言 * HTML的简介 超文本标记语言. * 是网页最基础的语言. * 都是由标签所组成的. * HTML的基本格式 <html> <head> ...