HTML5標準學習 - 編碼

来源:http://www.cnblogs.com/shouce/archive/2016/03/18/5290687.html
-Advertisement-
Play Games

相信每一個前端工程師都或多或少遇上過“亂碼”這位仁兄,無論你的基礎有多麼扎實,在生產的過程中都免不了偶爾和“亂碼”兄弟喝上幾杯茶吧。作為一個前端工程師,你是如何指定一個頁面的編碼的呢?你知道瀏覽器是怎麼識別編碼的嗎? 首先,一個很簡單的例子,用遇簡的HTML頁面來看看各瀏覽器下有什麼不同: 最簡HT


相信每一個前端工程師都或多或少遇上過“亂碼”這位仁兄,無論你的基礎有多麼扎實,在生產的過程中都免不了偶爾和“亂碼”兄弟喝上幾杯茶吧。作為一個前端工程師,你是如何指定一個頁面的編碼的呢?你知道瀏覽器是怎麼識別編碼的嗎?

首先,一個很簡單的例子,用遇簡的HTML頁面來看看各瀏覽器下有什麼不同:

<!DOCTYPE html>

最簡HTML,<head><body>都沒有內容,伺服器也不給出具體的編碼聲明,直接從本地打開,各個瀏覽器下查看頁面的編碼:

瀏覽器顯示編碼備註
IE6 UTF-8  
IE8 UTF-8  
IE9 GB2312 系統預設字元集
Firefox3.5 GBK2312 系統預設字元集
Firefox4.0 ISO-8859-1 西歐語言,英語預設編碼
Chrome GBK 系統預設字元集
Opera 中文-自動檢測 應該也是GB2312

從表格中可以看出,對於沒有使用任何手段聲明編碼的頁面,各瀏覽器有著不同的解析。當然在最簡的頁面中,無論用什麼編碼(當然前提是ASCII的超集)都沒有影響,但足以表現出正確設置編碼的重要性。

編碼聲明

HTML4和HTML5分別採用了一個章節來闡述編碼聲明的方法,可以點擊這裡查看HTML4的相關章節點擊這裡查看HTML5的相關章節

首先,何為編碼?編碼即是通過一定的方式,指定瀏覽器(或稱用戶代理)以一種特殊的演算法來解析位元組流,以得到真正正確的內容。在HTML的標準中,編碼可以使用別名來表示。編碼的別名來自於IANA的定義,只有在該列表中出現的編碼才可以被瀏覽器識別。因此如果把UTF-8寫成UTF8,瀏覽器就有可能完全不予理睬。另外,編碼別名是大小寫不敏感的。

在HTML4中,提出有3種方法指定頁面的編碼,根據優先順序高低依次是:

  1. HTTP頭裡的Content-Type欄位後跟隨字元集。
  2. 使用<meta http-equiv="Content-Type">標簽來聲明。
  3. 對於部分外部資源,如<script>標簽載入的js文件,可以通過標簽上的charset屬性聲明。

這個自然沒有什麼疑問,需要註意的是,通過<meta http-equiv="Content-Type">標簽來聲明頁面的話,當瀏覽器遇上該標簽時,如果發現自己使用的編碼與標簽聲明的不符,是會回到頭裡重新解析頁面的。這會導致頁面的一部分被重新解析,因此如果試圖使用標簽的方式聲明編碼的話,建議將標簽儘可能地寫在前面。一個最佳實踐是寫在<head>標簽之後,任何其他標簽之前。關於這一點,Google PageSpeed也有相應的介紹

時代演進

但是隨著時間的推移,開發者漸漸發現了一件事。就如同DOCTYPE的最簡聲明一樣,其實瀏覽器在讀取<meta>標簽的編碼的時候,並不是嚴格地按照標準進行的。總而言之,由於在HTML的解析階段,基於在Tokenizer階段之前就必須確定好頁面的編碼,因此瀏覽器不可能像分析DOM樹一樣,在DOM樹構建的時候再分解<meta>標簽的結構,取出其中的http-equivcontent屬性,再確定編碼。

現實中,瀏覽器做了一件非常簡單的事,來讀取<meta>標簽定義的編碼:

  1. 確定這是一個<meta>標簽,這根據HTML解析的狀態機,由"<"字元加上"meta"字元串就能確定。
  2. 查找該字元串(此處還沒有標簽的概念,只是個字元串),找到一個子字元串"charset"。
  3. 再向後讀,忽略掉所有的空格字元,找到第一個有意義的字元c。
    • 如果c不是"="這個字元,則回到第2步繼續找。
    • 如果c是"="這個字元,繼續向下走。
  4. 再跳掉所有的空格字元和單引號、雙引號等,向後掃描,直到遇上單引號、雙引號、空格字元、結束標簽等不應該出現的字元為上,截取其中掃描得出的字元串s。
  5. 分析s,得到編碼別名。

從上面的演算法,不難發現,下麵幾種寫法,其實都能讓瀏覽器正確地識別出編碼:

  • <meta http-equiv="Cotnent-Type" content="text/html; charset=utf-8" />
  • <meta charset="utf-8" />
  • <meta charset=utf-8 />
  • ……以及其他很多古怪的寫法。

於是,隨著歷史的推進,終於有一天,各瀏覽器廠商們坐在了一起,開始討論這個問題……最終他們驚奇地發現各自的實現非常相似(也許根本就是相互借鑒),所以他們決定將這種方式變成一個標準……最後,再經過漫長的討論,HTML5中廣為人愛的編碼聲明方式就誕生了。在HTML5中,稱其為“meta charset元素”,其最簡形式如下:

<meta charset=utf-8>

當然這是HTML的語法,如果遵從XHTML並覺得XHTML更加親切地話,寫成<meta charset="utf-8" />也是沒問題的。

而前文所述的具體獲取編碼的演算法也被詳細地記錄在案,可以在這裡看到

到了HTML5時代,標準再次對編碼的聲明方式做了修正和細化,總得來說有以下的區別:

  • HTML5允許使用BOM來決定編碼,但僅支持UTF-16的BOM(即U+FEFF),且沒有說明BOM指定編碼的優先順序如何。
  • HTML5添加了meta charset標簽。
  • HTML5規定如果一個頁面沒有指定編碼,則使用ASCII作為其編碼,而HTML4則規定瀏覽器可以根據所處的環境自行選擇。

其他雜項

除了編碼的基本聲明方式外,標準中還有不少需要註意的細節:

  • 如果使用<meta>標簽聲明編碼的話,該編碼只能是ASCII的超集編碼。可以簡單地認為ASCII超集就是支持ASCII的256個字元的編碼。
  • HTML5非常推薦使用UTF-8編碼。
  • 標準中提出不要使用UTF-32、JIS_C6226-1983、JIS_X0212-1990、HZ-GB-2312、JOHAB等字元集,並禁止使用CESU-8、UTF-7、BOCU-1和SCSU字元集。但事實上瀏覽器卻至少能識別UTF-7。
  • 對於想要嚴格遵守XHTML的開發者,應當使用XML聲明來指定編碼,即<?xml version="1.0" encoding="UTF-8" standalone="no" ?>。但是這個在IE6下會影響到DOCTYPE,所以開發者也不得在這一點上給予妥協,乖乖地去用HTML的聲明方式。
  • 關於現實中各編碼聲明方式的優先順序,以及一些其他需要註意的細節,這篇文章值得一讀。

最佳實踐

  • 儘可能使用HTTP頭指定編碼。
  • 儘可能使用UTF-8,或者至少全站所有資源使用統一編碼。
  • 如果想使用UTF-16,就給文件加上BOM,以確定是Little Endian還是Big Endian的。
  • 如果使用<meta>標簽指定編碼,可以不使用http-equiv的形式,但儘可能讓標簽出現在前面,至少保證在任何非ASCII字元之前。
  • 鏈接外部的腳本,如果無法確定編碼相同的話,加上charset屬性。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們現在做的一些非業務,如:日誌、事務、安全等都會寫在業務代碼中(也即是說,這些非業務類橫切於業務類),但這些代碼往往是重覆,複製——粘貼式的代碼會給程式的維護帶來不便,AOP就實現了把這些業務需求與系統需求分開來做。這種解決的方式也稱代理機制。 先來瞭解一下AOP的相關概念,《Spring參考手冊
  • 我是在ubuntu14.14 安裝的 lnmp。 部分擴展。均已安裝好,但是我用apt-get 方式安裝 redis和curl擴展時,我的配置都設置但是從phpinfo裡面看沒有響應的配置項。 於是我找在我phpinfo 載入的是 /etc/php5/fpm/php.ini 下的配置文件,我用php
  • 文章結尾有常用命令的圖表哦!git 配置基礎配置別名配置換行符配置推薦配置core.autocrlfcore.safecrlf記住我git命令詮釋大全git clonegit initgit addgit brachgit tag打包上線啦 git archive任務簡報 git shortlog常...
  • 在elasticsearch中,有時會想要通過索引日期來篩選查詢的數據,此時就需要用到日期數學表達式。 更多內容參考 "Elasticsearch翻譯彙總" 基於日期數學表達式的索引 模式如下: 其中各個欄位含義為: static_name 是索引的靜態部分 date_math_expr 是日期的表
  • Atitit.複合文檔的格式 標準化格式 1. Docfile1 2. Iso Cdf cd file1 3. Zip1 4. Ooxml1 5. Odf :OpenDocument Format2 5.1.1. 本質2 6. 參考3 paip.docfile二進位複合文檔 前言Docfile Do
  • 本文分為技術篇、產業篇、應用篇、展望篇四部分 2006年項目成立的一開始,“Hadoop”這個單詞只代表了兩個組件——HDFS和MapReduce。到現在的10個年頭,這個單詞代表的是“核心”(即Core Hadoop項目)以及與之相關的一個不斷成長的生態系統。這個和Linux非常類似,都是由一個核
  • 首先,描述一下問題。由於需要後臺取出數據,遍歷展示在table中,大體如下: 後臺取出的是 Map<String , List<Object>>,下麵是我寫得比較朴素一點的寫法: 以上方法,如有不妥之處,請予以指正。望與大家多多交流。 當然jquery的$.each(map,function(key
  • 本節教程將繼續帶領大家完善教學demo 將要學習的demo效果圖如下所示 1. 如何導入完整項目 本節示例demo請參考下載地址,可以導入到設計器中學習。 2. 完善主框架在上一節教程搭建主框架中大家已經學會瞭如何主框架,本節教程使用上一節未完成的demo。 我們分析一下demo機構,通過點擊Bot
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...