UTF-8 BOM(EF BB BF)


原標題:link標簽和script標簽跑到body下面,網頁頂部有空白,出現“鍩匡豢”亂碼,UTF-8 BOM,EF BB BF

來自:http://tunps.com/link-and-script-goes-under-body-tag

 

最近在做一個簡單的記賬系統,用php+mysql。在要完工的時候發現了一個問題,研究了2天的時間才有了答案。

以下是頁首的裁圖:

頁面的頭部有空白區域。有的人可能懷疑是css的margin,padding,border沒有重置為0造成的。其實不然,我已經將這幾個屬性重置為0。

而且在firebug下面查看HTML代碼會發現link標簽和script表情跑到body下面:

並且body標簽下面和link標簽之間有空行。

我自詡的查看我的模板文件是沒有任何問題的,想了很久最后實在是沒轍了,跑到Stackoverflow高手雲集的地方去提問

有個人提出了是頁面中存在stray text。

You've got some stray text content inside the , before the tag. The browser sees the text and decides this means you're starting the main document body but have forgotten to include the tag.

This is actually valid—if inadvisable—in HTML4: the end-tag and start-tag are both optional. This is how you can have just Hello! as a valid HTML document. But it's not permissible in XHTML, so if you validate your document you should get a “character data is not allowed here” error at the point the stray text occurs.

The browser then parses the rest of the document as body content, putting the inside the body (which is not valid, but which is nonetheless commonplace). It ignores the real when that comes along because it already has a body.

If you can't see the stray text, perhaps it's an invisible character like U+00A0 No-break space or—most likely for Chinese documents—U+3000 Ideographic space , which you may get when you press space in some input method modes. These characters won't be visible, but they're not ‘ignorable whitespace’ like a normal U+0020 Space or newline, so they trigger ‘text content’ processing and force the .

就是說頁面存在瀏覽器不能忽略的空白,比如U+0020活U+3000之類的。

我的php腳本全部使用的是utf-8編碼,html頁面的charset也就是utf-8,我強制讓瀏覽器把頁面用其他編碼來解析,比如GB2312,然后出現了如下圖的情況:

空白的部分出現了亂碼,而且內容都是“鍩匡豢”,這下子更是把我搞糊塗了。我按照SO上面bobince兄的建議,把模板頁傳到W3C markup validator上面去檢查,得出來如下結論:

大概意思是說,UTF-8中的BOM編碼在一些編輯器或者是瀏覽器中支持不好,可能會出現問題。

然后網上搜索了關於Byte Order Mark的信息:

在UCS 編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應該出現在實際傳輸中。UCS規范建議我們在傳輸字節流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。這樣如果接收者收到FEFF,就表明這個字節流是Big-Endian的;如果收到FFFE,就表明這個字節流是Little- Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。

UTF-8不需要BOM來表明字節順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF。所以如果接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。

Windows就是使用BOM來標記文本文件的編碼方式的。

然后我用UltraEdit的16進制編輯模式查看代碼,都是EF BB BF開頭的,說明都是帶BOM的。我手動的將所有文件轉成UTF-8 without BOM。頁面終於正常了。link,script標簽乖乖的跑到head下面,網頁頂部空白消失。oh yeah。這就是搞了2天的答案。

最后我在網上隨便下載了知名php程序的utf-8版,發現都是UTF-8 without BOM的。

那么我們繼續回頭看看出現問題的現象就有答案了。“鍩匡豢”在頁面頭部出現多次的原因是首頁處理文件index.php require_once了多個類和庫文件,而那些庫和類文件都是用的帶BOM的UTF-8,所有PHP無法識別,直接將EF BB BF輸出,在charset="utf-8"的頁面中是空白,在GB2312的頁面中的輸出的就是一個稀有漢字。不信可以查鍩匡豢這幾個字的GB2312代碼是多少:

UTF-8編碼是變長的,1—6個字節。其中漢字編碼,是3個或4個字節。而恰好EF BB BF多次出現,兩個EF BB BF組成EFBB BFEF BBBF ,而EFBB BFEF BBBF就是“鍩匡豢”的UTF-8編碼。這也是很多網站頁面頂部出現“鍩”加一個方框。

看來得找個時間惡補編碼知識了。

 

相關閱讀:

[1] 字節順序標記.http://zh.wikipedia.org/zh-cn/%E4%BD%8D%E5%85%83%E7%B5%84%E9%A0%86%E5%BA%8F%E8%A8%98%E8%99%9F.2013-06-19

[2]PHP源碼編碼與轉換:搞定首行為空和“鍩匡豢”.http://chensd.com/2011-09/php-source-convert-gbk-big5-to-utf8.html.2013-06-19

[3]【轉】PHP源碼編碼與轉換:搞定首行為空和“鍩匡豢”.http://www.cnblogs.com/fzzl/archive/2012/11/20/2780015.html.2013-06-19


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM