什麼是 URL 編碼?
URL 編碼(也稱百分號編碼)是 RFC 3986 定義、用於在 URL 中傳輸資料的機制。對在 URL 中具有保留語意的字元(例如 ? / # & =)或非 ASCII 可列印字元,會被改寫為一個或多個 %XX 三元組,其中 XX 是該位元組的十六進位表示。解碼時按位元組反向還原。
百分號編碼只是一種傳輸格式,不是安全機制。任何收到編碼字串的人都可以輕易解碼;不要把編碼誤認為加密或雜湊。
如何選擇模式
本工具提供開發者最終都會遇到的三種編碼模式。所選模式決定了哪些字元會被編碼。
Component 模式(encodeURIComponent)。當你要把單一值嵌入 URL 的某個位置時使用 —— 查詢字串值、路徑片段、fragment 等。它會編碼所有 URL 保留字元,因此結果放在任何位置都是安全的。
Whole URL 模式(encodeURI)。當你已經持有一條拼好的 URL,只想轉義真正不安全的字元(空格、非 ASCII)時使用。它會保留 : / ? # & = + 等結構性字元,讓 URL 保持可解析。
Form 模式(application/x-www-form-urlencoded)。當你建構 Content-Type 為 application/x-www-form-urlencoded 的 HTTP 請求主體時使用。空格轉為 +,換行符歸一化為 CRLF(%0D%0A),字元集與瀏覽器提交 HTML 表單時送出的內容一致。
保留字元參考表
| 字元 | Component | Whole URL | Form |
|---|---|---|---|
| (space) | %20 | %20 | + |
| ! | ! | ! | %21 |
| " | %22 | %22 | %22 |
| # | %23 | # | %23 |
| $ | %24 | $ | %24 |
| % | %25 | %25 | %25 |
| & | %26 | & | %26 |
| ' | ' | ' | %27 |
| ( | ( | ( | %28 |
| ) | ) | ) | %29 |
| * | * | * | * |
| + | %2B | + | %2B |
| , | %2C | , | %2C |
| / | %2F | / | %2F |
| : | %3A | : | %3A |
| ; | %3B | ; | %3B |
| = | %3D | = | %3D |
| ? | %3F | ? | %3F |
| @ | %40 | @ | %40 |
| [ | %5B | %5B | %5B |
| ] | %5D | %5D | %5D |
| ~ | ~ | ~ | %7E |
| %0A | %0A | %0D%0A | |
| 中 | %E4%B8%AD | %E4%B8%AD | %E4%B8%AD |
Component 會編碼除 A–Z a–z 0–9 - _ . ! ~ * ' ( ) 以外的全部字元。Whole URL 在此基礎上額外保留結構性字元 ; , / ? : @ & = + $ # !。Form 的編碼集與 Component 相同,並額外編碼 ! ' ( ) ~(但不編碼 *),把空格換成 + 而非 %20,並把 \n / \r / \r\n 歸一化為 \r\n(編碼為 %0D%0A)—— 這正是瀏覽器提交 application/x-www-form-urlencoded 表單時送出的位元組序列。
常見用例
以程式方式建構安全的查詢字串:手動拼接 /search?q=[value] 這類 URL 時,把值經過 Component 模式編碼,確保值中出現的 & 或 = 不會汙染外層 URL 結構。
在 URL 中嵌套 URL:當你把一個 URL 作為另一個 URL 的參數傳遞(例如 OAuth 回呼位址)時,必須用 Component 模式編碼內層 URL,而非 Whole URL —— 否則內層 URL 中的 / : ? & 會被外層 URL 誤判為結構符。
使用 fetch 送出表單:當你 POST 一個 Content-Type: application/x-www-form-urlencoded 的請求主體時,主體必須按 Form 模式編碼。本工具的 Form 模式輸出與瀏覽器送出的位元組一致。
局限性
URL 編碼不是加密。任何人都能透過一次函式呼叫解碼其輸出;絕不要用編碼來隱藏秘密。
模式選擇很關鍵。用 Component 模式編碼整條 URL 會把它打亂(每個 / 都變成 %2F)。用 Whole URL 模式編碼查詢值會留下危險的保留字元(值中的 & 仍會被消費端當作參數分隔符)。不確定時請選 Component。