要在 JavaScript 中將 HTML 轉換為文字——也就是將 HTML 標記嵌入為可用的 JavaScript 字串——最可靠的做法是將標記序列化為單一 JavaScript 字串常值,並對所選分隔符號無法容納的每個字元進行跳脫。以 const 開頭的賦值 const name = "..."、const name = '...' 或 const name = `...` 是規範的輸出形式。跳脫問題主要來自三個字元:所選的分隔符號(雙引號、單引號或反引號)、反斜線本身,以及 ECMAScript 在一般字串中禁止的換行字元或控制字元。樣板字串常值會帶來第二個危險,因為 ${ 這個序列會開始一個內插運算式。轉換過程是掃描 UTF-16 輸入,根據所選模式跳脫相關字元,並輸出一個 const 宣告。不會建立 DOM、不會進行剖析,而且標記會逐字保留,包括空白、註解、實體,以及任何格式錯誤的標籤。產生的結果就是一般的 JavaScript 原始碼,可以直接貼到檔案中求值,不會出現意外狀況。

how to convert html to text in javascript
HTML 轉 JavaScript:選擇正確的引號模式

在 JavaScript 中定義 HTML 序列化

本文所說的 HTML 序列化純粹是文字層面的處理。您貼上的 HTML 會被視為一串 UTF-16 字碼單元,每個字元都會完整保留。標籤、屬性順序、行內樣式、註解、像 & 這類具名實體,甚至是格式錯誤的標記,在輸出中都會保持為文字。這與從 HTML 中萃取純文字的做法有本質上的差異——後者會移除標籤以取得可讀的字串,而序列化則會完整保留標記,僅用 JavaScript 的字串語法加以包裹。這個區別很重要,因為基於剖析器的轉換器可能會悄悄地把屬性順序標準化、把標籤名稱轉為小寫、修補未閉合的標籤,或捨棄對空白敏感的內容,例如預先格式化的程式碼、script 標籤或樣板片段。對於稍後要透過 innerHTML 渲染、餵給樣板引擎,或重新組回文件的內容,這些悄悄的變更可能會破壞輸出結果。HTML 轉 JavaScript 轉換器刻意避開這個範疇:它執行的是文字序列化,而非 HTML 剖析。

三種引號模式有何不同

JavaScript 引擎將每種引號樣式視為各自的字串常值語法。雙引號與單引號除了分隔符號之外可互換使用:在雙引號模式下,原始的雙引號會中斷字串;而在單引號模式下,原始的撇號(單引號)會中斷字串。兩種模式都會將換行字元與歸位字元編碼為跳脫序列,而非允許原始的換行字元,且反引號在兩者中皆保留給樣板字串常值使用。反斜線會優先跳脫,因此您 HTML 中既有的跳脫序列——例如 Windows 路徑、正則表達式語法,或已跳脫的 JSON 字串——在 JavaScript 的求值步驟中會原封不動地保留下來。

樣板字串常值的運作方式則不同。它允許多行來源而無需明確的 \n 跳脫,這讓手寫的標記更易閱讀。但它帶來兩個新的危險:未跳脫的反引號會關閉字串常值,而 ${ 這個序列會開啟 JavaScript 運算式。轉換器會跳脫這兩者,因此貼上的 HTML 不會意外變成可執行的內插程式碼。輸出是一般的無標籤樣板字串常值;刻意需要執行階段內插的開發者應在事後自行加入並逐一檢查每個運算式,而非讓貼上的輸入自行產生程式碼。將產生的名稱限制在保守的 ASCII 子集內,可避免在不同執行階段之間出現視覺上易混淆的 Unicode 字元與版本相關的意外。

引號模式需要跳脫的分隔符號是否允許多行?內插風險適用情境
雙引號 (")"否(換行字元已跳脫)無含有大量撇號但沒有雙引號的 HTML
單引號 (')'否(換行字元已跳脫)無含有大量雙引號但沒有撇號的 HTML
樣板字串常值 (`)` 與 ${是有(已跳脫)可能同時包含兩種引號的可讀多行 HTML

四個步驟將 HTML 轉換為 JavaScript 字串

  1. 依照最終字串中應呈現的樣貌,逐字貼上 HTML 來源。請勿事先跳脫、標準化或美化標記。標籤、註解、空白與實體都應與您執行階段所期望的內容逐位元組相同,因為轉換器將輸入視為純文字,而非已剖析的文件。
  2. 輸入一個非保留字的 ASCII JavaScript 變數名稱。此欄位接受以字母、底線或錢號開頭的識別字,並拒絕 class、const、for、return 等保留字。產生的宣告一律使用 const;只有在確實需要重新賦值,或您的模組模式要求不同的宣告時,才手動變更關鍵字。
  3. 選擇雙引號、單引號或樣板字串常值。挑選與您 HTML 中主要分隔符號相符的模式;若兩種引號都頻繁出現,樣板模式可讀性最高。點選轉換以產生賦值。
  4. 複製賦值並貼到您的程式碼中。在隔離的測試環境——主控台、JavaScript 線上編輯環境或單元測試——中求值該字串常值,並斷言其結果字串與您原本的輸入完全相等,再將其整合到渲染或樣板邏輯中。根據 ECMAScript 字串常值語法的規範,這個來回比對檢查是確認每個跳脫都落在引擎預期位置的唯一方法。

會破壞 JavaScript 字串常值的字元

ECMAScript 字串常值語法禁止一組少數字元出現在一般字串中,並在樣板字串常值中保留其他字元。轉換器會依所選模式跳脫每一個分類,以 UTF-16 字碼單元掃描輸入,而非將其重新剖析為標記。反斜線會優先跳脫,使路徑、正則表達式文字與既有的跳脫在 JavaScript 求值產生的賦值後仍保有其原始字元。換行字元 (\n)、歸位字元 (\r)、行分隔符 U+2028 與段落分隔符 U+2029 會被明確編碼,以確保跨執行階段的可攜性——引擎會將 U+2028 與 U+2029 視為換行字元,雖然它們看起來像一般的空白。U+0000 至 U+001F 的控制字元會被跳脫,避免它們消失或在無聲無息中終止字串常值。在樣板模式下,${ 會被跳脫,使貼上的內容不會變成可執行的運算式語法;反引號也會被跳脫,避免字串常值提前關閉。

字元或序列雙引號模式單引號模式樣板模式
" (雙引號)跳脫 (\")保留保留
' (單引號/撇號)保留跳脫 (\')保留
` (反引號)保留保留跳脫 (\`)
${ (內插開頭)保留保留跳脫 (\${)
\ (反斜線)跳脫 (\\)跳脫 (\\)跳脫 (\\)
\n 與 \r (原始換行字元)跳脫跳脫跳脫
U+2028 與 U+2029跳脫跳脫跳脫
U+0000–U+001F 控制字元跳脫跳脫跳脫

MDN 樣板字串常值參考文件以人類可讀的形式說明了這套語法,包括為何特殊 Unicode 分隔符需要明確的跳脫,以及為何 String.raw 在來源 HTML 含有 ${ 時並無法消除內插風險。

出貨前進行來回比對測試

只有在真實的 JavaScript 引擎求值後,產生的字串能逐字元重現原始標記時,轉換才算正確。最快速的檢查方式是單行比對:將字串常值指派給變數,再用 === 與輸入進行比對。任何不符之處都代表某個分隔符號被遺漏、有未跳脫的控制字元,或上游某處不小心進行了 Unicode 標準化。HTML 轉 JavaScript 轉換器正是以這個精確的來回比對特性為核心——每一條跳脫規則的存在,都是為了讓求值後的字串等於輸入,而內部的語法測試涵蓋了八個外部案例,包括引號、反斜線、換行字元、樣板分隔符、內插語法與 Unicode 行分隔符。請在 JavaScript 線上編輯環境等隔離環境中執行此檢查,而非在您的正式程式碼中,以免某個錯誤的跳脫悄悄蔓延到渲染出來的頁面。若要一次處理多個片段,請遵循 批次 JavaScript 線上編輯環境執行中的迭代指引,讓每個測試在不同的引號模式下都保持隔離且可重現。

文字序列化的限制

序列化並不會驗證、清理或渲染 HTML。若產生的字串將被指派給 innerHTML、與不受信任的資料結合,或被當作程式碼求值,目標端仍然需要配合情境的跳脫、維護良好的清理器,以及嚴格的內容安全政策 (Content Security Policy)。在不需要標記時,請使用 textContent,並避免僅為了顯示 HTML 而使用 eval 或 new Function。轉換器同樣不會建立 DOM、重新排序屬性、標準化大小寫、修補未閉合的標籤,或將 HTML 轉為 JSX——這個狹隘的範疇是刻意為之,因為剖析器可能會悄悄改寫對空白敏感的內容,例如 script 區塊、style 標籤或樣板片段。若您需要標記驗證或 DOM 建構,請使用為目標格式設計且有持續維護的剖析器。轉換完全在目前的瀏覽器分頁中執行:HTML 不會被上傳、儲存、執行、預覽或傳送至伺服器,也不需要帳號或新增任何相依套件。對於正式環境的產生器,請在隔離的測試中求值複製的賦值,並斷言其結果字串與原始輸入完全相等——這個來回比對檢查能與轉換器所依據的外部語言標準 fixtures 互補,但無法取代它們。