跳到主要內容

開發者工具 / 036

URL 編碼解碼

提供 URL 編碼與解碼,並比較 encodeURI、encodeURIComponent 的結果;也可拆解網址的協定、主機、路徑與查詢參數。

貼上內容後會立即處理,並同時顯示兩種函式的結果。

為什麼做這個

encodeURI 與 encodeURIComponent 很容易混用,差別在於哪些網址結構字元會被保留。把兩種結果並排,再搭配網址拆解,可以更快確認參數與編碼內容。

這個工具怎麼用

貼上內容就會立即處理。編碼模式會同時給 `encodeURIComponent` 與 `encodeURI` 兩種結果——如果兩者相同(內容裡沒有網址結構字元)會合併成一個結果,不然就並列讓你直接比較。

兩個函式的差別是要不要保留網址的結構字元。 `encodeURI` 會保留 `:/?#[]@!$&'()*+,;=`,因為它的設計目的是編碼「一整個網址」,那些字元是網址語法的一部分不能動。`encodeURIComponent` 則連它們一起編碼,因為它的用途是編碼「要放進參數的值」。

選錯的後果很具體:用 `encodeURI` 編一個含有 `&` 的參數值,那個 `&` 不會被編碼,接收端會把它當成參數分隔符,值就被截斷了。規則很簡單——編整個網址用 encodeURI,編要塞進參數的值用 encodeURIComponent。 實務上後者用到的機會多得多。

解碼模式除了還原 `%XX` 序列,也能處理不成對的百分號——那種情況會直接告訴你解碼失敗,而不是靜靜地丟出半截結果。編碼模式下方還會把網址拆成協定、主機、路徑與查詢參數,參數值已經幫你解碼過。

用實際字串比較最清楚。把 `a b&c=d/é?` 交給 `encodeURIComponent` 會得到 `a%20b%26c%3Dd%2F%C3%A9%3F`:空格、`&`、`=`、`/`、`?` 全部被編碼,`é` 是 UTF-8 的兩個位元組 C3 A9,所以變成 `%C3%A9`。把整串網址 `https://x.com/a b?q=你好&r=1#h` 交給 `encodeURI` 則是 `https://x.com/a%20b?q=%E4%BD%A0%E5%A5%BD&r=1#h`,協定、斜線、問號與井字號都保留,只有空格與中文被編碼。

如果把整串網址 `https://x.com/?a=1` 誤用 `encodeURIComponent`,結果是 `https%3A%2F%2Fx.com%2F%3Fa%3D1`,已經不能當連結使用。簡單的判斷方式:處理「整個網址」用 `encodeURI`,處理「放進網址的某一個值」(查詢參數的值、路徑中的一段)用 `encodeURIComponent`。

常見問題

encodeURI 跟 encodeURIComponent 到底該用哪個?

編碼「整個網址」用 encodeURI,編碼「要放進查詢參數的值」用 encodeURIComponent。實務上絕大多數情況是後者。判斷方式:如果你編的東西裡面的 `/`、`?`、`&`、`=` 是網址語法的一部分,用 encodeURI;如果它們只是資料內容,用 encodeURIComponent。

為什麼我的參數值被截斷了?

很可能是用了 encodeURI 去編碼參數值。值裡面的 `&` 沒有被編碼,接收端就把它當成下一個參數的開始。改用 encodeURIComponent 即可。這個工具把兩種結果並列,就是為了讓這個差別一眼看得出來。

空格為什麼有時候變 %20、有時候變 +?

`%20` 是標準的百分號編碼。`+` 是舊的 `application/x-www-form-urlencoded` 表單格式規則,只在查詢字串的部分成立。JavaScript 的兩個 encode 函式都輸出 `%20`,這個工具也是。解碼別人給的內容時要注意來源用的是哪一種。

解碼失敗是什麼原因?

最常見的是內容裡有不成對的百分號,例如單獨的 `%` 或 `%ZZ` 這種不是有效十六進位的序列。這時 `decodeURIComponent` 會丟 URIError。另一個可能是內容經過多次編碼,需要多解幾輪。

中文網址(IDN)處理得了嗎?

查詢參數與路徑裡的中文可以正常編碼解碼。網域本身的中文(例如 台灣.tw)用的是 punycode,是另一套機制,這個工具的網址拆解會顯示瀏覽器轉換後的結果。

%E4%BD%A0 這種編碼是怎麼來的?

百分號編碼先把字元轉成 UTF-8 位元組,再把每個位元組寫成 `%` 加兩位十六進位。「你」的 UTF-8 是三個位元組 E4 BD A0,所以是 `%E4%BD%A0`。這也是中文網址複製出來會變得很長的原因。