欢迎转载,请支持原创,保留原文链接:blog.ilibrary.me

UTF-8 BOM

UTF-8 编码的文件可以分为no BOM 和 BOM两种格式。

何谓BOM? “EF BB BF” 这三个字节就叫BOM,BOM的全称叫做”Byte Order Mark”.在utf-8文件中常用BOM来表明这个文件是UTF-8文件,而BOM的本意实在utf16中用来表示高低字节序列的。在字节流之前有BOM表示采用低字节序列(低字节在前面),而utf8不用考虑字节序列,所以其实有无BOM都可以。UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是 “奎”还是“乙”?

如果文件保存时,选择了使用 BOM,那么就可能会出现 headers already sent 的问题。 因为 Web 服务器软件可能不认识 BOM,所以就把 BOM 的两个特殊字节当做字符发送给浏览器了。 这时再调用 session_start() 等函数,就会出现 headers already sent 的问题。 所以解决此问题最根本的方法就是在保存 UTF8 编码文件时,不要使用 BOM。

微软的记事本 Word 等只能正确打开含BOM的UTF8文件,然后UltraEdit却恰恰相反,回把BOMutf8文件 误认为ascii编码。

UTF-8的BOM是 EFBBBF,因为UE载入UTF-8文件会转成Utf16,上述的EFBBBF 在Utf16中是FFFE(Unicode-LE的BOM),UltraEdit不认识BOM又加多一個BOM,所以有2个FFFE。文件就被它破坏了。

当应用程序的文件使用 UTF8 编码时,在保存文件时,一定要注意 BOM 的问题。

遇到过的坑

  1. Ruby解析csv的时候第一个cell名称解析不对。a = csv.headers[0]值应该为”公司”, 长度应该为2, 可是测试a.length出来为3, a.bytes可以看到前面几个bytes为[239, 187, 191]. 这导致csv[0][“公司”]读取值为nil. 解决办法,用utf-8不带BOM保存.
  2. nginx更新证书以后无法正常加载,提示
    SSL_CTX_use_PrivateKey_file("/var/www/dg/shared/config/dealglobe.com.key") failed (SSL: error:0906D06C:PEM routines:PEM_read_bio:no start line:Expecting: ANY PRIVATE KEY error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib)
    

    后来发现是UTF-8 BOM文件无法解析,换成ANSI就可以了。

UTF-8 BOM转UTF-8

用visual studio code打开UTF-8 BOM文件,点击右下角UTF-8 BOM, 在点击弹出菜单里面的”Save with Encoding” -> UTF-8, 保存即可.