HTML 實體編碼的運作原理
HTML 實體是一種字元參考,瀏覽器解析後會還原為單一字元。五個保留的 HTML 字元(<、>、&、"、')在文字以 HTML 渲染時必須編碼;其他字元則視文件編碼而定,為可選項目。
- 選擇模式與範圍. 編碼模式會逐字元處理輸入。解碼模式則掃描輸入中的實體模式。範圍切換決定只編碼五個 HTML 保留字元,或同時將所有非 ASCII 碼位重新編寫。
- 選擇實體樣式. 具名實體(
©)在原始碼中易於閱讀。十進位參考(©)和十六進位參考(©)可涵蓋所有 Unicode 碼位,無需名稱。較舊的電子郵件用戶端和 XML 解析器偏好數字形式。 - 逐字元處理輸入. 編碼時,我們讀取每個碼位並在約 200 個常用具名實體的內建表中查找。未匹配的字元回退至數字形式。解碼時,使用單一正規表示式一次匹配
&name;、&#NNN;和&#xHH;。 - 映射至字元. 具名匹配透過反向表解析。數字匹配以十進位或十六進位基底透過
String.fromCodePoint處理。未知的具名實體保持原樣,確保不完整輸入的往返轉換不遺失任何資料。 - 即時模式. 開啟即時模式後,每次按鍵都會以 150 毫秒的防抖延遲重新執行轉換。當您微調程式片段並希望在貼入範本前立即獲得回饋時非常實用。
為什麼要編碼 HTML 實體
- 防止使用者輸入破壞頁面版面. 當使用者在評論框中輸入多餘的
<時,若直接將該文字插入 HTML,整個頁面的其餘部分將被重寫。先編碼保留字元,瀏覽器就會渲染字元本身,而非將其解析為標籤的開始。 - 保持屬性值有效. 在 HTML 屬性中嵌入引號字串,需要將嵌入的引號替換為
"(雙引號屬性)或'(單引號屬性)。否則解析器會提前關閉屬性,導致其餘部分成為多餘的標記。 - 防止儲存資料中的意外 HTML. 記錄檔、錯誤報告和聊天匯出通常包含真正的角括號和 & 符號。在將這些資料貼入文件頁面前進行實體編碼,可確保其以文字形式顯示,而不會觸發渲染器或連結自動偵測功能。
- 安全分享程式碼片段. 在部落格文章、電子郵件或 Slack 訊息中發布範例標籤(如
<script>alert(1)</script>)時,需對角括號編碼,使程式片段顯示而非執行。RSS 內容和 JSON-LD `description` 欄位同樣適用此技巧。
常見應用場景
實體編碼出現在任何執行時期將原始文字組合成 HTML 的地方——即使框架通常會自動處理,手動工具在框架未處理的情況下仍然有用。
- 伺服器渲染範本:Jinja2、ERB、Twig 和 Handlebars 預設會自動轉義,但 raw 區塊和 `safe` 標記會關閉此功能——此編解碼器讓您確認轉義會產生的結果。
- 電子郵件與電子報撰寫:許多 ESP 範本引擎不會自動轉義合併欄位,因此使用者提供的姓名中的彎引號和版權符號需要預先編碼。
- 文件與程式碼範例:將範例 HTML 標籤貼入 Markdown 部落格文章或靜態網站片段時,需要對角括號編碼,使渲染器將其視為可見文字。
實際範例
將 <script>alert('hi')</script> 貼入輸入框,模式設為「編碼」、樣式選「具名」、範圍選「最小化」。輸出結果為 <script>alert('hi')</script>。將樣式切換為「數字十六進位」,相同輸入會產生 <script>alert('hi')</script>。再將模式切換為「解碼」,貼入已編碼的字串,即可還原原始標籤。
FAQ
什麼是 HTML 實體?
HTML 實體是字元參考,瀏覽器解析頁面時會將其替換回單一字元。共有三種形式:具名(如 & 代表 &)、十進位數字(&)和十六進位數字(&)。五個保留的 HTML 字元(<、>、&、"、')在文字插入 HTML 時必須編碼。其餘約 2,225 個具名實體涵蓋符號、重音字母和希臘字母,在文件編碼為 UTF-8 時為可選項目。
何時應使用具名實體與數字實體?
當您希望原始碼易於閱讀時(審查範本時看到 © 一目了然),使用具名實體。當消費端較舊或更嚴格時,使用數字形式(十進位或十六進位)——XML 解析器、舊版電子郵件用戶端和部分訂閱閱讀器僅識別 HTML5 具名實體的一小部分,但全部支援數字形式。十六進位在注重安全性的情境中較受青睞,因為它與規格文件中使用的 Unicode 碼位表示法一一對應。
解碼器是否能處理十六進位實體(如 &)?
可以。解碼器使用單一正規表示式,一次匹配所有三種實體形式:&name;、&#NNN; 和 &#xHH;。數字匹配以十進位或十六進位基底透過 String.fromCodePoint 解析。混合輸入(同一字串中同時包含具名和數字實體)可正確解碼,未知名稱保留為字面文字,確保不完整輸入的往返轉換不遺失資料。
此工具用於不受信任的輸入是否安全?
此編解碼器完全在瀏覽器中運行,不會將您的輸入傳送至任何地方。輸出是否可以安全嵌入取決於使用情境。實體編碼適用於 HTML 正文和屬性值情境,涵蓋 OWASP 規則 #1 的案例。JavaScript 情境(行內事件處理器、`<script>` 區塊)、CSS 情境和 URL 情境各需自己的編碼規則——單靠實體編碼並不足夠。對於伺服器端深度防禦,請搭配使用情境感知範本引擎(如 DOMPurify)或框架的自動轉義功能。
瀏覽器端實體編碼位於使用者輸入與渲染 HTML 之間的邊界。在本地執行轉換表示您可以核對框架應產生的輸出,而無需將原始文字傳送至第三方工具。