首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

HTML 字符實體與轉義完整手冊:Java、JavaScript、PHP 多語言實戰

     編輯:Java 綜合教學

HTML 字符實體與轉義完整手冊:Java、JavaScript、PHP 多語言實戰

在 Web 開發中,`<`、`>`、`&`、`"` 等字符在 HTML、XML、JSON、URL、SQL、Shell 等上下文中具有特殊含義,直接輸出會導致結構破壞、XSS 攻擊、解析錯誤。掌握字符實體、轉義規則及各語言實現,是安全開發的基本功。

一、為什麼需要轉義?

  • HTML 上下文:`
    ` 被視為標籤,`&` 用於實體引用。若用戶輸入 `` 直接輸出,瀏覽器會執行腳本 (XSS)。
  • 屬性上下文:`` 中的 `"` 會截斷屬性值。
  • JavaScript 上下文:字符串中 `\n`、`\`、`'`、`"` 需轉義。
  • URL 參數:`&`、`=`、`#`、`%`、`空格` 需百分號編碼。

二、HTML 字符實體分類大全

1. 必須轉義的核心字符 (XML/HTML 5 核心)

字符實體名稱實體編號 (十進制)實體編號 (十六進制)說明
<&lt;&#60;&#x3C;小於號,標籤開始
>&gt;&#62;&#x3E;大於號,標籤結束
&&amp;&#38;&#x26;和號,實體開始符
"&quot;&#34;&#x22;雙引號,屬性值界定
'&apos; (XML/HTML5)&#39;&#x27;單引號,屬性值界定

原則:在 HTML 文本節點與屬性值中,**務必**將以上 5 字符替換為實體。現代框架 (React, Vue, Thymeleaf) 默認自動轉義。

2. 空白與排版實體

顯示實體名稱編號用途
 &nbsp;&#160;不換行空格 (最常用)
 &ensp;&#8194;半個中文字符寬度 (en space)
 &emsp;&#8195;一個中文字符寬度 (em space)
 &thinsp;&#8201;窄空白 (thin space)
​&zwnj;&#8204;零寬非連接器
‍&zwj;&#8205;零寬連接器 (Emoji 合成用)

&#10; / &#xA;&#10;換行符 (HTML 中白間折疊,需 `
` 或 CSS `white-space: pre`)

3. 國際化與符號實體 (常用精選)

字符實體名稱編號字符實體名稱編號
©&copy;&#169;®&reg;&#174;
™&trade;&#8482;€&euro;&#8364;
×&times;&#215;÷&divide;&#247;
§&sect;&#167;&para;&#182;
•&bull;&#8226;…&hellip;&#8230;
←&larr;&#8592;→&rarr;&#8594;
↑&uarr;&#8593;↓&darr;&#8595;
″&Prime;&#8243;′&prime;&#8242;
″&Prime;&#8243;′&prime;&#8242;

4. 數學與希臘字母 (精選)

字符實體名稱編號字符實體名稱編號
∀&forall;&#8704;∃&exist;&#8707;
∈&isin;&#8712;∉&notin;&#8713;
∑&sum;&#8721;∏&prod;&#8719;
√&radic;&#8730;∞&infin;&#8734;
≈&asymp;&#8776;≠&ne;&#8800;
≤&le;&#8804;≥&ge;&#8805;
⊂&sub;&#8834;⊃&sup;&#8835;
α&alpha;&#945;β&beta;&#946;
γ&gamma;&#947;δ&delta;&#948;
π&pi;&#960;σ&sigma;&#963;
Ω&Omega;&#937;ω&omega;&#969;

三、Java 實現:HTML 轉義與反轉義

1. 手動實現 (教學用)

public static String escapeHtml(String input) {
    if (input == null) return "";
    StringBuilder sb = new StringBuilder(input.length() + 16);
    for (char c : input.toCharArray()) {
        switch (c) {
            case '<': sb.append("<"); break;
            case '>': sb.append(">"); break;
            case '&': sb.append("&"); break;
            case '"': sb.append("""); break;
            case '\'': sb.append("'"); break; // HTML5 支援 '
            default: 
                if (c > 0x7E || c < 0x20) { // 非可打印 ASCII,可選轉數字實體
                    sb.append("&#").append((int) c).append(";");
                } else {
                    sb.append(c);
                }
        }
    }
    return sb.toString();
}

2. 生產級庫 (推薦)

  • Apache Commons Text:`StringEscapeUtils.escapeHtml4(input)` / `unescapeHtml4(escaped)`
  • OWASP Java Encoder:`Encode.forHtml(input)` (專為 XSS 防護設計,效能極高)
  • Spring Framework:`HtmlUtils.htmlEscape(input)` / `HtmlUtils.htmlUnescape(input)`
  • Thymeleaf:模板中默認 `${var}` 自動轉義,`${#strings.escapeHtml(var)}` 手動調用。

3. Maven 依賴

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-text</artifactId>
    <version>1.11.0</version>
</dependency>
<!-- OWASP Encoder -->
<dependency>
    <groupId>org.owasp.encoder</groupId>
    <artifactId>encoder</artifactId>
    <version>1.2.3</version>
</dependency>

四、JavaScript 實現

1. 瀏覽器原生 DOM 方法 (最安全、最簡單)

function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text; // 瀏覽器自動轉義
    return div.innerHTML;
}

function unescapeHtml(html) {
    const div = document.createElement('div');
    div.innerHTML = html;
    return div.textContent || div.innerText;
}

2. 正則替換 (Node.js / 無 DOM 環境)

const escapeMap = {
    '&': '&', '<': '<', '>': '>',
    '"': '"', "'": ''', '/': '/' // / 針對  攻擊
};
function escapeHtml(str) {
    return String(str).replace(/[&<>"'\/]/g, c => escapeMap[c]);
}

3. JavaScript 字符串轉義序列 (字面量中)

序列字符
\b退格
\f換頁
\n換行
\r回車
\tTab
\'單引號
\"雙引號
\\反斜槓
\xHHLatin-1 字符 (2位十六進制)
\uHHHHUnicode 字符 (4位十六進制)
\u{HHHHH}Unicode 碼點 (ES2015+)

五、PHP 實現

// HTML 轉義 (默認雙引號,ENT_QUOTES 含單引號)
$escaped = htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
// 反轉義
$original = htmlspecialchars_decode($escaped, ENT_QUOTES);

// 所有字符轉實體 (含多字節)
$allEntities = mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8');
// 反向
$original = mb_convert_encoding($allEntities, 'UTF-8', 'HTML-ENTITIES');

// 全局輸出轉義 (配置 php.ini 或入口文件)
ini_set('default_charset', 'UTF-8');
// 針對特定輸出流自動轉義 (慎用,影響性能)
// ob_start('mb_output_handler'); // 需 mbstring

六、Python 實現

import html
escaped = html.escape(text, quote=True)  # 含雙引號
original = html.unescape(escaped)

七、不同上下文的轉義策略總表

上下文必須轉義字符推薦方法錯誤示範
HTML 文本節點< > & 框架自動 / OWASP Encoder手動拼接未轉義變量
HTML 屬性值< > & " ' 同上 + 確保屬性用雙引號包裹屬性無引號或單引號未轉義
JavaScript 字符串\ ' " < > / \n \rJSON 序列化 (`JSON.stringify`) / JS 模板字面量直接拼接變量到腳本
URL 查詢參數& = # % 空格 非 ASCII`encodeURIComponent()` / `URLSearchParams`手動拼接字符串
SQL 語句' " \ NUL**參數化查詢 (PreparedStatement)**字符串拼接 SQL
Shell 命令空格 $ ` \ " ' ; | &避免 `Runtime.exec`,用 `ProcessBuilder` 列表參數字符串拼接命令

八、編碼轉換:字符串 ↔ Unicode 轉義 (\uXXXX)

Java 實現

public static String toUnicode(String str) {
    StringBuilder sb = new StringBuilder();
    for (char c : str.toCharArray()) {
        if (c <= 0x7F) sb.append(c); // ASCII 保留
        else sb.append(String.format("\\u%04x", (int) c));
    }
    return sb.toString();
}

public static String fromUnicode(String unicodeStr) {
    // 簡單實現,實際需處理 \uXXXX 模式
    return unicodeStr; // 建議用 Apache Commons Text: StringEscapeUtils.unescapeJava()
}

JavaScript 實現

function toUnicode(str) {
    return [...str].map(c => c.charCodeAt(0) > 0x7F 
        ? '\\u' + c.charCodeAt(0).toString(16).padStart(4, '0') 
        : c).join('');
}
// 反向: 瀏覽器自動解析 \uXXXX 字面量,或用 JSON.parse('"' + str.replace(/"/g, '\\"') + '"')

九、總結:安全輸出黃金法則

  1. 永遠不要信任輸入:用戶輸入、數據庫讀取、第三方 API 返回、日志文件均視為非受信。
  2. 輸出時轉義,而非輸入時:存儲原始數據,根據輸出上下文 (HTML/JS/URL/SQL) 選擇對應編碼器。
  3. 使用成熟庫/框架內建機制:手寫轉義極易疏漏 (如遺漏 `/` 導致 `` 繞過)。
  4. 設置正確 Content-Type 與 Charset:`Content-Type: text/html; charset=UTF-8` 避免瀏覽器編碼猜測導致繞過。
  5. 啟用 CSP (Content Security Policy):作為纵深防禦,限制腳本來源、禁止內聯腳本。

字符轉義看似瑣碎,實則是 Web 安全的第一道防線。建立「上下文感知輸出編碼」的思維模型,比記住具體實體表格更重要。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved