1.什么是BOM?
BOM是用來判斷文本文件是哪一種Unicode編碼的標記,其本身是一個Unicode字符("\uFEFF"),位於文本文件頭部。
在不同的Unicode編碼中,對應的bom的二進制字節如下:
Bytes Encoding
FE FF UTF16BE
FF FE UTF16LE
EF BB BF UTF8
所以我們可以根據文件頭部的幾個字節和上面的表格對應來判斷該文件是哪種編碼形式。
2. 如何查看你文件的BOM字符?
BOM頭在記事本中是看不到的
以UTF8為例,新建一個1.txt文件,然后打開文件 輸入 hello world 然后另存為 此時更改文件的編碼格式 由默認的ANSI 即GB2312(國標2312)編碼改成UTF8
然后通過下面的node代碼,來打印該文本文件的buffer 就可以看到我們所說的BOM頭字符
let fs = require('fs'); fs.readFile('./1.txt',function(err,data){ console.log(data) }) // <Buffer ef bb bf 68 65 6c 6c 6f 20 77 6f 72 6c 64> // 前三個字節就是對應的我們UTF8編碼的文本的BOM頭字符
3.存在的問題?
雖然BOM字符起到了標記文件編碼的作用但是他並不屬於文件的內容部分,所以會產生一些問題:
1.在某些使用場景下就會有問題。例如我們把幾個JS文件合並成一個文件后,如果文件中間含有BOM字符,就會導致瀏覽器JS語法錯誤。
2.PHP就不能識別bom頭,PHP並不會忽略BOM,所以在讀取、包含或者引用這些文件時,會把BOM作為該文件開頭正文的一部分。根據嵌入式語言的特點,這串字符將被直接執行(顯示)出來。由此造成即使頁面的 top padding 設置為0,也無法讓整個網頁緊貼瀏覽器頂部,因為在html一開頭有這3個字符呢!
4.如何去掉UTF8編碼的記事本文件的BOM頭
方法一:在文件另存為的時候選擇無BOM頭的UTF8編碼
方法二:使用node中的文件模塊獲取文件的buffer數據並去掉前三個字節,代碼如下:
function deleteUtf8BomHead(path) { let buf = fs.readFileSync(path); if (buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf) { buf = buf.slice(3) } return buf } console.log(deleteUtf8BomHead('./1.txt'));// <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64> // 將GBK編碼的buffer轉化成utf8的字符串 // 在這里我們要引入一個庫 iconv-lite let iconv = require('iconv-lite'); fs.readFile('./2.txt',function (err, data) { console.log(data,'qq'); let str = iconv.decode(data,'gbk'); console.log(str); })