HTML 實體編碼工具
線上轉換 HTML 實體字元,支援編碼與解碼,有效防止 XSS 攻擊
選擇轉換方式
什麼是 HTML 實體編碼?
安全相關結果不能孤立判斷,還要結合金鑰、使用情境、演算法選擇和可信來源一起評估。
如何使用
如何使用
- 在左側輸入框中輸入或貼上要轉換的文字
- 點選對應按鈕選擇編碼或解碼方式
- 結果會自動顯示在右側
- 點選「複製」按鈕將結果複製到剪貼簿
轉換方法
鍵盤快捷鍵
- Ctrl + EHTML 實體編碼
- Ctrl + DHTML 實體解碼
編碼提示
- 將使用者可見的文字插入 HTML 原始碼前先進行編碼,特別是當文字可能包含角括號、引號或 & 符號時。
- HTML 實體編碼能避免標記被當作內容解讀,但它只是 XSS 防禦的一環,無法取代依上下文的輸出跳脫。
使用場景
技術原理
HTML 使用 WHATWG HTML Living Standard 定義的兩種字元參照。具名實體參照以 & 開頭、; 結尾,取自 WHATWG 維護的 entities.json 表(截至目前規範約有 2,231 個名稱,包括不含尾部分號的舊式別名如 &)。數字實體參照使用十進位(<)或十六進位(<)形式的 Unicode 碼點,可編碼 U+0000 至 U+10FFFF(代理區 U+D800-U+DFFF 除外)的任何字元。五個必須跳脫以確保 HTML 語法安全的字元為 &(&)、<(<)、>(>)、"(")和 '(');注意 ' 屬於 XML 和 HTML5,但在 HTML 4.01 中無效,因此 OWASP 建議在雙引號屬性中使用數字形式 ' 以相容舊版解析器。 本工具的編碼為單次替換:替換順序很重要,因為 & 必須先跳脫,否則為 < 和 > 插入的實體前綴會被再次跳脫為 &lt;。解碼則利用瀏覽器的 HTML 解析器,將輸入賦值給分離元素的 innerHTML 再讀取 textContent;這會派發至 HTML 規範中的官方詞法分析器狀態機(第 13.2.5.72 節字元參照狀態至第 13.2.5.80 節),可正確解析具名、十進位和十六進位形式,包括缺少分號的異常輸入。完整編碼模式的數字編碼逐碼點遍歷字串,使用 String.prototype.codePointAt 處理佔用 UTF-16 代理對的增補平面字元(例如表情符號 U+1F600 變為 😀 而非兩個代理參照)。 XSS 防禦需要根據上下文進行跳脫,而非僅做 HTML 實體編碼。OWASP 跨站腳本攻擊防禦速查表定義了五種不同的上下文:HTML 主體、HTML 屬性(有引號與無引號)、JavaScript 資料(<script> 內)、CSS 和 URL。HTML 實體跳脫僅涵蓋前兩種上下文。JavaScript 上下文應使用 JSON.stringify 的 \xHH 或 \uHHHH 跳脫,URL 上下文需要 encodeURIComponent(RFC 3986 百分比編碼),而內聯事件處理器則結合了兩種規則,因為其值會同時經過 HTML 和 JavaScript 解析器。Content-Security-Policy 標頭搭配 script-src 'self' 並移除 'unsafe-inline' 是現代縱深防禦層,可捕捉跳脫錯誤,而 innerHTML、document.write 和 setAttribute('on*', ...) 等 DOM 接收端應替換為 textContent 或框架管理的綁定(React 的 JSX、Vue 的雙大括號),這些預設會自動跳脫。
- 具名參照:WHATWG entities.json 中約有 2,231 個條目;五個必須跳脫的名稱為 & < > " '(' 僅限 HTML5/XML,HTML 4.01 不支援)
- 數字參照:十進位 &#DDDDD; 和十六進位 &#xHHHH; 涵蓋 U+0000 至 U+10FFFF;代理區 U+D800-U+DFFF 及 U+0000 NULL 依 HTML 規範為無效
- 跳脫順序:& 必須先替換,否則後續跳脫插入的 & 前綴會被雙重編碼;編碼為 O(n),使用 5 項查找表
- 透過 DOMParser 解碼:賦值給分離元素的 innerHTML 會呼叫 HTML 規範詞法分析器(字元參照狀態,第 13.2.5.72-80 節),可處理不含尾部分號的舊式實體
- 增補平面字元處理:使用 String.prototype.codePointAt 和 for...of 迭代,使表情符號和 CJK 擴展 B 字元(U+10000+)產生單個 &#NNNNN; 而非兩個代理參照
- 上下文感知跳脫(OWASP XSS 防禦速查表規則 #0):HTML 主體、HTML 屬性、JavaScript、CSS 和 URL 各需不同的跳脫;僅靠 HTML 實體無法阻止 JS 或 URL 接收端的 XSS
- 縱深防禦:Content-Security-Policy 的 script-src 'self'(RFC 風格)、DOMPurify 白名單消毒用於富文本輸入,以及在原生 DOM 程式碼中優先使用 textContent/innerText 而非 innerHTML
範例
基本元素編碼
輸入: <script>alert(1)</script>
輸出: <script>alert(1)</script>
Use: 在渲染使用者輸入的內容時,避免瀏覽器將文字當成真正的標籤解析屬性值編碼
輸入: <div title="Hello & world">
輸出: <div title="Hello & world">
Note: 屬性內的引號與 & 符號會被編碼為實體,避免值跳脫引號範圍頁面中顯示 URL
輸入: search?q=hello&lang=en
輸出: search?q=hello&lang=en
Use: 將 URL 插入 HTML 前應先編碼 &,否則解析器可能將後續字元視為格式錯誤的實體非 ASCII 字元(完整編碼)
輸入: CJK characters like 中文
輸出: 完整 UTF-8 數字格式 中文(若頁面支援命名實體亦可使用)
Use: 將任意 Unicode 字元安全嵌入舊版 HTML;現代頁面通常直接使用 UTF-8常見問題
HTML 編碼會轉換哪些字元?
SGML 的五個保留字元:& → &、< → <、> → >、" → "、' → '(或 ')。也可選擇將非 ASCII 字元轉成數值實體(&#xNN;),以相容於不支援 UTF-8 的舊系統。
什麼時候需要 HTML 編碼?
只要把使用者提供的文字嵌入 HTML 內容,就應該編碼。不編碼是 XSS 漏洞的根源。HTML 內文、屬性值、JavaScript 上下文、CSS 上下文與 URL 上下文都需要編碼——每種情境的規則略有不同。
' 和 ' 有什麼差別?
兩者都產生單引號。' 是 HTML5 才加入的,在 HTML4 或某些舊版郵件使用者端中無效——若輸出可能由舊系統讀取,請改用 '。本頁預設輸出 ' 以取得最大相容性。
為什麼輸出裡仍含有 &?
如果輸入本身已包含類似 & 的 HTML 實體,編碼後會變成 &amp;——這是正確的,因為輸入裡的 & 是普通字元而非實體。如果你的來源已經是實體編碼過的,應先解碼再重新編碼。
Emoji 會被轉換嗎?
Emoji 是合法的 Unicode,現代 HTML 把它們當一般字元處理——除非目標系統強制只接受 ASCII,否則無需編碼。開啟「非 ASCII 轉數值實體」選項可將其轉為 &#xNNNN; 形式。
HTML 編碼跟 URL 編碼一樣嗎?
不一樣。URL 編碼(百分比編碼)是把不安全字元換成 %NN 序列以便用於 URL;HTML 編碼則是把字元換成具名或數值實體以用於 HTML。請依情境挑選正確的工具,混用會造成雙重編碼的錯誤。
轉換是在本機完成的嗎?
是的。編碼與解碼都在你的瀏覽器中進行,貼上的文字不會被上傳。