万恶的BOM: 与 \ufeff
最近在搞一个 Sass 文件的编译插件,主要使用 node-sass 来进行编译,在这过程中遇到一个蛮坑的小问题。
在不压缩的情况下使用 node-sass 进行编译的样式文件没有什么问题,可以正确的编译出该有的样式。可是当进行压缩时,就出了问题了。压缩后的文件莫名奇妙的在文件最开头多了几个奇怪的字符:
。
本着有什么不懂先 Google 的原则,搜索 ""
。发现 stack overflow 上有个相关的问题:How do I remove  from the beginning of a file?。原来这是一个叫 BOM(Byte Order Mark)的东西,字节顺序标记,出现在文本文件头部,Unicode 编码标准中用于标识文件是采用哪种格式的编码。
在网页上使用 BOM 是个错误。BOM 设计出来不是用来支持 HTML 和 XML 的。
上面这句来自 「带 BOM 的 UTF-8」和「无 BOM 的 UTF-8」有什么区别?网页代码一般使用哪个? 的回答。我想补充一下,更可恶的事情是 BOM 在 CSS 中。
由于在文件开头多出了一个 BOM,使得压缩后的所有样式都失效了。一开始我尝试在文件最开头加上 @charset "utf-8"
,但是并没有什么用。不过发现了在加上 @charset "utf-8"
后,变成了这样:
![](https://www.notion.so/image/https%3A%2F%2Fahonn-me.oss-cn-beijing.aliyuncs.com%2Fimages%2Ftnh93.jpg?table=block&id=f8996adc-9e3a-41a6-8cea-11acd88276e3&cache=v2)
BOM
多出来的一个小红点,鼠标移上去显示 "\ufeff"
。找到罪魁祸首了,搜索 "\ufeff"
发现有篇关于 JavaScript 中处理 BOM 的文章:BOM 和 JavaScript 中的 trim。
最后得到解决方案,在编译后的样式中进行替换,移除 \ufeff
:
css = css.replace('\ufeff', '');
虽然解决方案蛮简单的,但是在搜索答案与编码测试的过程中学到了蛮多。编码问题还是要注意的,虽然无法避免遇到 utf-8 with BOM,但是也应该尽量只保存为 utf-8 without BOM 编码格式。如果遇到奇怪的字符,那八成就是编码问题了。