這是前端最常見的編碼坑。JavaScript 內建的 btoa() 看起來就是 Base64 編碼函式,但只要輸入含中文就會拋出例外:
btoa("鴻創")
// ✕ InvalidCharacterError:
// The string to be encoded contains characters outside of the Latin1 range.
原因是 btoa 誕生於 Base64 只用來處理二進位資料的年代,它假設輸入的每個字元都落在 Latin-1(0–255) 範圍內,一個字元對應一個位元組。而「鴻」的 Unicode 碼位是 U+9D3B,遠超過 255,函式無從得知該怎麼拆成位元組。
要編碼中文,必須先把字串轉成 UTF-8 的位元組序列,再做 Base64:
// 編碼
const bytes = new TextEncoder().encode("鴻創");
const b64 = btoa(String.fromCharCode(...bytes));
// 解碼
const bin = atob(b64);
const arr = Uint8Array.from(bin, c => c.charCodeAt(0));
const text = new TextDecoder().decode(arr);
本工具採用的就是這個做法,所以中文、日文、韓文與 Emoji 都能正確往返。如果你曾經在別的線上工具遇到「編碼後解不回來」或「變成亂碼」,多半就是對方少了 UTF-8 這一層。
這點必須講清楚,因為實務上被誤用的情況相當多。Base64 是編碼,不是加密——它沒有金鑰,任何人拿到都能立刻還原。
它的用途是讓二進位資料能在只允許文字的通道中傳輸,例如把圖片內嵌進 HTML 的 data: URI、在 JSON 欄位裡塞二進位內容、或處理電子郵件附件(MIME)。
絕對不要用 Base64 來「保護」密碼、API 金鑰或個人資料。真正需要保密時請使用 AES 等加密演算法,可以使用我們的線上加解密工具。
標準 Base64(RFC 4648 第 4 節)使用 64 個字元:A-Z、a-z、0-9、+、/,並以 = 補齊長度。問題在於 + 和 / 在網址中另有意義:
/ 是路徑分隔符號,放在網址裡會被誤判成目錄層級+ 在查詢字串中會被某些伺服器解讀成空格= 是參數的鍵值分隔符號因此 RFC 4648 第 5 節定義了 URL-safe 變體:把 + 換成 -、/ 換成 _,並省略結尾的 =。JWT(JSON Web Token)用的就是這種變體,這也是為什麼 JWT 可以直接放在網址或 HTTP 標頭中。
兩者的差別在於「哪些符號要保留」,選錯會產生難以察覺的 bug:
| 函式 | 會編碼 | 不編碼 | 用途 |
|---|---|---|---|
encodeURIComponent |
/ ? : @ & = + $ , # 也一併編碼 |
A-Z a-z 0-9 - _ . ! ~ * ' ( ) |
編碼查詢參數的值,最常用 |
encodeURI |
僅編碼空白、中文等非法字元 | 保留 / ? : @ & = 等網址結構符號 |
編碼一整條完整網址 |
實際情況說明差異。假設你要把一個網址當成參數傳遞:
const target = "https://ttsc.tw/?a=1&b=2";
// ✕ 錯誤:用 encodeURI,冒號斜線都沒編碼
"/go?url=" + encodeURI(target)
// → /go?url=https://ttsc.tw/?a=1&b=2
// 後端會把 a=1、b=2 誤認成自己的參數
// ✓ 正確:用 encodeURIComponent
"/go?url=" + encodeURIComponent(target)
// → /go?url=https%3A%2F%2Fttsc.tw%2F%3Fa%3D1%26b%3D2
判斷原則:如果你在組裝參數的「值」,一律用 encodeURIComponent。
當你要把使用者輸入的內容顯示在網頁上,必須把 <、>、&、"、' 轉成 HTML 實體,否則對方可以注入 <script> 標籤執行任意程式碼,這就是 XSS(跨站腳本攻擊)。
使用者輸入: <script>alert(1)</script>
跳脫之後: <script>alert(1)</script>
畫面顯示: <script>alert(1)</script> ← 當成文字,不會執行
不過在實際開發中,更推薦使用 textContent 而不是 innerHTML,或使用會自動跳脫的樣板引擎(React、Vue 預設都會跳脫)。手動跳脫容易漏掉情境——例如放進 HTML 屬性、JavaScript 字串或 CSS 中,各自需要不同的跳脫規則。這個工具的 HTML 實體功能主要用於檢視與除錯,不建議當成正式的防護手段。
\uXXXX 是在只能使用 ASCII 的環境中表示任意字元的方式。你會在這些地方看到它:JSON 檔案(部分工具會把非 ASCII 字元轉成跳脫序列)、Java 的 .properties 設定檔、以及各種原始碼的字串常數中。
要注意的是,超出基本多文種平面的字元(碼位大於 U+FFFF,例如多數 Emoji)需要用兩個 \uXXXX 組成的代理對(surrogate pair)表示:
"鴻" → \u9d3b (1 個)
"😀" → \ud83d\ude00 (代理對,2 個)
本工具會正確處理代理對,轉換後再轉回來不會遺失字元。這也是為什麼 JavaScript 中 "😀".length 會是 2 而不是 1。
本工具完全在瀏覽器中執行,輸入的內容不會傳送到任何伺服器,因此即使要處理含機敏資訊的字串也不必擔心。詳見隱私權政策。