原由是公司iOS端居然加载除了HTML代码,百思不得其解,查文献,原来如此...php
UTF-8 不须要 BOM,尽管 Unicode 标准容许在 UTF-8 中使用 BOM。
因此不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称做「Unicode」而又不详细说明,这也是微软的习惯)。
BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是由于这样能够把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 以外的操做系统里会带来问题。linux
「UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF。
UTF-8 的网页代码不该使用 BOM,不然经常会出错。这是一个小例子: 为何这个网页代码 <head> 内的信息会被浏览器理解为在 <body> 内?c++
另附《The Unicode Standard, Version 6.0》之 3.10 D95 UTF-8 encoding scheme 的一段话:
While there is obviously no need for a byte order signature when using UTF-8, there are occasions when processes convert UTF-16 or UTF-32 data containing a byte order mark into UTF-8. When represented in UTF-8, the byte order mark turns into the byte sequence. Its usage at the beginning of a UTF-8 data stream is neither required nor recommended by the Unicode Standard, but its presence does not affect conformance to the UTF-8 encoding scheme. Identification of the byte sequence at the beginning of a data stream can, however, be taken as a near-certain indication that the data stream is using the UTF-8 encoding scheme.
http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf程序员
---------------------------------------------------------
首先,BOM是啥。这个就不解释了,Wikipedia上很详细。http://en.wikipedia.org/wiki/Byte_order_mark。
在网页上使用BOM是个错误。BOM设计出来不是用来支持HTML和XML的。要识别文本编码,HTML有charset属性,XML有encoding属性,不必拉BOM撑场面。虽然理论上BOM能够用来识别UTF-16编码的HTML页面,但实际工程上不多有人这么干。毕竟UTF-16这种编码连ASCII都双字节,实在不适用于作网页。sql
其实说BOM是个坏习惯也不尽然。BOM也是Unicode标准的一部分,有它特定的适用范围。一般BOM是用来标示Unicode纯文本字节流的,用来提供一种方便的方法让文本处理程序识别读入的.txt文件是哪一个Unicode编码(UTF-8,UTF-16BE,UTF-16LE)。Windows相对对BOM处理比较好,是由于Windows把Unicode识别代码集成进了API里,主要是CreateFile()。打开文本文件时它会自动识别并剔除BOM。Windows用这个有历史缘由,由于它最初脱胎于多代码页的环境(ANSI环境)。而引入Unicode时Windows的设计者又但愿能在用户不注意的状况下同时兼容Unicode和非Unicode(Multiple byte)文本文件,就只能借助这种小trick了。相比之下,Linux这样的系统在多locale的环境中浸染的时间比较短,再加上社区自己也有足够的动力轻装前进(吐槽:微软对兼容性的要求确实是到了很是偏执的地步,任何一点破坏兼容性的作法都不容许,以致于不少时候是本身绑住本身的双手),因此干脆一步到位进入UTF-8。固然中间其实有一段过渡期,好比从最初全UTF-8的GTK+2.0发布到基本上全部GTK开发者都弃用多locale的GTK+1.2,我印象中至少经历了三到四年。shell
BOM不受欢迎主要是在UNIX环境下,由于不少UNIX程序不鸟BOM。主要问题出在UNIX那个全部脚本语言通行的首行#!标示,这东西依赖于shell解析,而不少shell出于兼容的考虑不检测BOM,因此加进BOM时shell会把它解释为某个普通字符输入致使破坏#!标示,这就麻烦了。其实不少现代脚本语言,好比Python,其解释器自己都是能处理BOM的,可是shell卡在这里,没办法,只能躺着也中枪。提及来这也不能怪shell,由于BOM自己违反了一个UNIX设计的常见原则,就是文档中存在的数据必须可见。BOM不能做为可见字符被文本编辑器编辑,就这一条不少UNIX开发者就不满意。编程
顺便说一句,即便脚本语言能处理BOM,随处使用BOM也不是推荐的办法。各个脚本语言对Unicode的处理都有本身的一套,Python的 # -*- coding: utf-8 -*-,Perl的use utf8,都比BOM简单并且可靠。另外一个好消息是,即便是必须在Windows和UNIX之间切换的朋友也不会悲催。幸好在UNIX环境下咱们还有VIM这种神器,即便遇到BOM挡道,咱们也能够经过 set nobomb; set fileencoding=utf8; w 三条命令解决问题。vim
最后回头想一想,彷佛也真就只有Windows坚持用BOM了。windows
P.S.:本问题是本身的第150个回答。忽然发现本身回答得不多不多⋯⋯
P.S. 2:忽然想起须要解释一下为何说VIM去除bomb的操做须要在UNIX下完成。由于VIM在Windows环境下有一个奇怪的bug,老是把UTF-16文件识别成二进制文件,而UNIX(Linux或者Mac均可以)下VIM则无问题。这个问题从VIM 6.8一直跟着我到VIM 7.3。目前尚不清楚这是VIM的bug仍是我本身那个.vimrc文件的bug。若有高手解答不胜感激。xcode
---------------------------------------------------------
有bom格式在开头会多出3个字节 EF BB BF ,主要用于识别编码。bom应该是windows特有的,在制做网页时会产生各类意想不到的问题,例如多输出了一个空行,影响PHP的session或者cookies功能(出现 header already sent错误),甚至可能引发页面的乱码(那3个字节影响了浏览器对页面编码的处理),所以老是推荐使用无bom编码。为了处理这个问题我甚至写了一个批量处理的PHP脚本。
---------------------------------------------------------
邸强,软件开发ing
张旭东、Mingyue Zhou、sapjax 赞同
几周前还在为BOM的问题苦恼着。。。
正如@梁海所说,“不含 BOM 的 UTF-8 才是标准形式”,的确是这样,无BOM使用得更多些,因此我的仍是推荐通常状况下用无BOM的形式吧,除非有问题的时候,再考虑换有BOM的。Windows系统保存的都是有BOM的,因此你能够看到,用记事本保存一个UTF-8的txt,实际上是有BOM的,这一点须要注意。另外不一样的文本编辑器对于有无BOM的称呼也略有不一样,好比EditPlus,有BOM的称为UTF-8+,无BOM的称为UTF-8,而在Notepad++中,有BOM的被称为标准UTF-8,而无BOM则被称为UTF-8无BOM。
---------------------------------------------------------
武龙飞,c/c++ 程序员,喜欢天文学,数学和心理学。
Weijing Huang、Bill Chan、icky R 赞同
如下文字出自个人博客内容,从另外一面解说不同的bom。
---------------------------------------------------------
字符编码相信是每一个程序员的噩梦,只要是有中文的地方,老是会遇到各类编码的问题,而且这种问题还很是难缠,尤为在linux上,由于上面不少软件都是针对英语国家开发的,是不会考虑其余语种编码问题。在遇到编码的无数大坑以后,我决定仔细研究下编码问题,由于这就像一道坎一直横在你面前,每次到这里你都会跌到,每次爬起来以后,你都若无其事,这样的人被称做战士,真正的战士。惋惜是个力量战士,作为新时代的智力战士,固然不能在那跌到而后又在这继续跌到。
文件的存储方式:
文件都有本身的存储格式,好比最多见的txt,cpp,h,c,xml ,png, rmvb各类格式,还有自定义格式。这些文件不管是什么格式,都是存储在计算机硬盘里的2进制格存储,对应不一样文件格式,有不一样的软件解析。这篇文章不谈文件是如何存储的,只谈文件是如何解析的。
文本文件解析:
文本文件对应于人类能够阅读的文本,如何从2进制转换为文本文件呢?起初因为计算机在美国发明,天然你们考虑的是英语如何表示,英语字母总共26个,加上特殊字符,128个字符,7位既一个byte便可表示出来。这个就是你们所熟知的ascill编码。对应关系很简单,一个字符对应一一个byte。
但很快发现,其余非英语国家的文字远远超过ascill码,这时候你们固然想统一一下,不一样国家出了本身不一样的编码方式,中国的gb2312就是本身作出来的编码方式,这样下去每一个国家都有本身的编码方式,来回转换太麻烦了。这时候出现了新的编码方式,unicode编码方式,想将编码统一,因此规定了每一个字符对应的unicode码。
一、不少文件都是ascii编码,若是用unicode 太浪费。
二、没有标志位说明该几个字节来解析为一个符号。
这时候拯救世界的utf出现了,utf是unicode的一种实现,只不过更聪明了。utf16是占用两字节,或者四字节,utf32是占用四字节。utf8是很聪明的一种表示方式。
一、对于单字节符号,字节第一位为0,后面7位表示字节编码。
二、对于n字节符号,第一字节的前n位都设为1,第n+1位为0,其他位位编码位置。
对于不一样的编码,在文本的最前方有不一样的标志,unicode 一般有两位来表示分别是ff fe, 或者feff, fffe表示big-endian 编码feff表示litte-endian编码。utf8是efbbbf来开头的。能够看出来utf-8是自解释的,因此不用带这个标志文件,大多数程序是能够识别的。但有些程序不能识别这个标志,好比php就会直接把这个标志当文本解析,不会忽略。相信不少遇到php输出文本解析乱码或者解析错误的同窗都遇到这样的问题。
最后说说如何去掉或者加上bom,若是有vim那最好不过了,去掉命令:
set encoding=utf-8
set nobomb
添加命令:
set encoding=utf-8
set bomb
---------------------------------------------------------
带 BOM 的 UTF-8 就是赤裸裸的流氓!!!!!!!!!
windows老是自作聪明的作一些别人没法理解的事情!!!UTF-8是不须要BOM头的~~~!!
从刚开始学习代码(实在不能称我作的东西为程序)到如今,不晓得被这个BOM头搞了多少次,特别是对于我这种彻底自学的人,知道找一个BUG须要多久多久不????
带不带BOM头区别就在于这个BOM头,祥见排名靠前的大神答案。windows特有的奇葩。请使用UTF-8 不带BOM头!!
它产生的BUG包含但不只限于:
锘 -- 感谢 @飞扬 提供,参考其答案
HTML空白行
div之间莫明的间隔
乱码!
若是你用ssl那么必定会有问题!!!
顺便再鄙视一下 SONY的记忆棒、IPHONE的接口~~
这种吐槽的东西就让它折叠吧
--------------------------------------------------------
带 BOM 的 UTF-8 很是操蛋,常常形成莫名其妙的问题。
---------------------------------------------------------
我都是用的UTF-8 without BOM,带BOM的常常出现乱码
---------------------------------------------------------
notepad++会自动添加为带Bom的utf8比较坑爹
---------------------------------------------------------
建议编程人员能使用 Mac 编程的尽可能使用Mac,Window是及其操蛋的操做系统。其次,若是咱们要读取三方的文件并以UTF-8格式解析的时候必定要注意去判断这个文件是否有BOM,例如:sql文件的解析执行。
---------------------------------------------------------
网页编程中用不用bom我就不说什么了,由于软件缘由没法使用的就更不能用了。
最近在学习用cocos2d-x,纯C++的编码,若是代码中有中文等的非ascii字符出现。发现会出错。代码是在mac 下用xcode 写的,放到windows 下用vs 编译。
最后把全部的源文件转成了带bom的格式后编译经过了,连接失败,这想这个就不是编码的问题了。
一般状况下,通常都 会认为在写C++代码的时候不要用中文,可是不少时候咱们程序员也有想本身看着舒服的时候,为神马就不能写中文了?
因而在windows 下写了一个helloworld.cpp 类型的文件,输出内容用中文,而后存为utf-8 带bom格式,再把它copy到mac 下用g++ 编译,发现成功经过而且可正常运行,用xcode打开源文件也正常显示。
因此,这里建议程序要在windows 和 mac 还有linux 上运行的话,源代码最好保存成utf-8 带bom的格式,这样比较通用一些。而用utf-16 不管大端仍是小端,g++ 都不认的。或者用utf-8 不带bom格式,而后代码不要出现非ascii 127之后的字符。
关于说utf-8 不带bom 才是标准的,我想应该是带用我的情绪的说法吧。真正的标准应该是bom是可选的,为何可选?由于有些时候不带bom会出错,就拿历史较久远的windows来说吧,不少国家的用户都在用windows ,其文件都是用其本地的ansi 编码来作的,好比大陆的GBK和GB2013,港台的big5,这些编码由于针对当地所用的字符制定的,因此呢,其存储文件较小,因此会大量使用,而且也大量存在着,微软不可能不考虑全球几十亿的用户的文件而盲目地修改解码方式,而且微软也是uncode 制定者之一,因此,带用bom的utf-8也是符合国际标准的。
或许是由于程序编写者的我的缘由,也许是考虑到效率,不少的程序没法正确区分一个utf-8文件是否有bom,因此致使了各类乱码的出现。
我的不想说哪一个是标准,也不想用语言去攻击哪一个公司或团体。微软在坚持使用bom上没有错,由于这是在为用户考虑的。也许给咱们这些写程序的带来了不便,可是,计算机最普遍的用户不是程序员。---------------------------------------------------------摘自:http://www.zhihu.com/question/20167122