URL 只允許一小組 ASCII 字元直接出現,其他所有東西都得先轉成 UTF-8 位元組、再寫成 %XX 這種百分比編碼。這個工具做的就是這件事的兩個方向:把文字轉成可以安全放進 query string 的形式,或把一串 %E4%B8%AD%E6%96%87 還原成看得懂的字。編碼與解碼用的是瀏覽器內建的 encodeURIComponent 與 decodeURIComponent,全程在你的裝置上完成,你貼上的內容不會被送出去——這點很重要,因為需要解碼的字串常常是含有 token、signature 或使用者 email 的 callback URL。
使用步驟
- 先用上方兩個分頁按鈕選方向:「編碼」把原始文字轉成百分比編碼,「解碼」把
%XX還原。切換方向時輸入框與結果都會被清空,這是刻意的,避免把編碼結果誤當成待解碼的輸入。 - 把內容貼進輸入框。編碼模式的欄位標題是「原始文字」,解碼模式是「URL 編碼字串」。
- 按下「編碼」或「解碼」(按鈕文字會跟著模式變)。這個工具不是邊打邊轉的,一定要按按鈕才會產生結果。
- 結果出現在下方「結果」欄,用右上角的複製按鈕帶走。「清空」會一次清掉輸入、結果與錯誤訊息。
- 解碼失敗時結果會是空的,下方顯示「無效的 URL 編碼字串」。這代表輸入裡有不合法的百分比序列,詳細原因見下方「注意事項」。
- 要做來回驗證(編碼後再解回來確認一致),得手動複製結果、切到另一個模式、再貼進輸入框——兩個模式共用同一組欄位,不會自動接續。
什麼時候用得上
組出安全的 query string 參數值
要把 台北 101 & 附近 這種含空格與 & 的字串塞進 ?q= 時,不編碼的話 & 會被伺服器當成參數分隔符,後半段直接變成另一個參數。編碼後得到 %E5%8F%B0%E5%8C%97%20101%20%26%20%E9%99%84%E8%BF%91,整串都是一個值,不會被拆開。
看懂 OAuth / 金流回跳 URL 裡的內容
第三方登入與金流的 callback 常把 redirect_uri、state 或錯誤訊息整段編碼後塞進參數,在 log 裡看到的是 https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback%3Fnext%3D%252Forders。解碼後才看得出原本的目標網址,也才會發現裡面的 %252F 是被編了兩次。
除錯「中文參數到後端就變亂碼」
把前端實際送出的字串貼進解碼模式,如果能還原成正確中文,問題就在後端的解碼或資料庫編碼;如果這裡就報錯或還原成問號亂碼,代表送出的位元組本身不是 UTF-8,問題在送出端。這一步能把責任範圍縮到一半。
手寫 curl 或 Postman 測試請求
手動測 API 時最容易在含 +、=、/ 的參數上翻車,例如 Base64 字串或 JWT。先在這裡把值編碼再貼進 URL,可以排除「參數被 URL 語法吃掉」這個變因。
限制與注意事項
- 這裡用的是
encodeURIComponent,它的設計對象是「URL 的一個片段」,不是整條 URL。因此:、/、?、#、&、=全都會被編掉。把https://a.com/b?c=d整條貼進來,會得到https%3A%2F%2Fa.com%2Fb%3Fc%3Dd——這在你要把整條網址當成某個參數的值(例如redirect_uri)時正是你要的;但如果你只是想讓一條網址裡的中文變成可用形式、同時保留://與?的結構,這個工具會編過頭。那種需求對應的是encodeURI,本工具沒有提供,正確做法是拆開來只編碼每個參數值。 - 空格一律編成
%20,不會編成+。+代表空格是application/x-www-form-urlencoded的規則(HTML 表單 GET 送出、以及 PHP、Java Servlet 等許多後端的 query 解析器都照這套走),不是 URL 規格。所以:若目標是模擬表單送出,你得自己把%20換成+;反過來解碼時,a+b會原封不動還原成a+b,不會變成a b,因為decodeURIComponent不認識這條規則。 - 正因為上一條,字面上的
+一定要編成%2B。?email=a+b@example.com這種沒編碼的寫法,在會做 form-urlencoded 解析的後端會讀成a b@example.com,email 就壞了——這是最常見也最難察覺的一種資料損壞。 A–Z a–z 0–9 - _ . ! ~ * ' ( )這 71 個字元不會被編碼。前面 66 個是 RFC 3986 的 unreserved 字元沒問題,但!、*、'、(、)在 RFC 3986 裡其實屬於 sub-delims,encodeURIComponent按舊的 RFC 2396 放過它們。多數情況無害,但在 OAuth 1.0 的簽章基底字串、AWS Signature V4 的 canonical query 這類要求嚴格編碼的場合,這 5 個字元必須手動改成%21、%2A、%27、%28、%29,否則簽章不會對。- 非 ASCII 一律先轉 UTF-8 再逐位元組編碼,所以長度會膨脹得很兇:中文字一個變 9 個字元(
中→%E4%B8%AD),基本 emoji 一個變 12 個(😀→%F0%9F%98%80),帶 ZWJ 的組合 emoji(例如家庭)一個會變成 36 個字元以上。IE 時代 2,083 字元的 URL 上限、以及現在許多 CDN 與 nginx 預設的 header 長度限制,用中文參數時很容易撞到。 - 這個工具只做百分比編碼這一件事。它不解析 URL 結構、不轉換網域名稱(含中文的網域要用 punycode
xn--那套,不是百分比編碼)、不做 Base64、也不會幫你判斷該編一層還是兩層。每按一次只處理一層。
常見問題
為什麼會出現「無效的 URL 編碼字串」?
decodeURIComponent 遇到不合法的百分比序列就會丟出 URIError,常見四種:(一)孤立的 %,例如把 折扣 100% 直接貼進解碼模式;(二)% 後面不是兩位十六進位數,例如 %ZZ;(三)序列被截斷,例如複製時只複製到 %E4 就斷了;(四)位元組組合起來不是合法的 UTF-8,例如來源其實是 Big5 或 Latin-1 編碼的舊系統字串。第四種這個工具救不回來,需要用能指定原始編碼的工具處理。
我解碼後還是看到 `%25` 或 `%2520`,怎麼辦?
那是被編碼了兩次。% 本身編碼後是 %25,所以第二次編碼會把 %20 變成 %2520。看到 %25 就是雙重編碼的指紋。處理方式是把結果複製起來、切到解碼模式再貼一次,每按一次剝掉一層,直到不再出現 %25。根本解法是找出程式裡哪一段對已經編過的值又編了一次,通常發生在「前端組好編碼字串,後端框架又自動編一次」的接縫上。
我貼上的內容會被上傳嗎?
不會。轉換完全靠瀏覽器內建的 encodeURIComponent 與 decodeURIComponent,在你的裝置上算完就結束,沒有任何請求帶著你貼上的內容出去。你可以斷網後再操作一次驗證:工具照樣正常運作。含有 access_token、signature 的 callback URL 可以放心貼進來。(頁面本身會載入廣告等第三方資源,那些請求不含你的輸入。)
編出來的 `%E4` 是大寫,別的工具給我小寫 `%e4`,哪個對?
兩個都對,也完全等價。RFC 3986 建議用大寫,encodeURIComponent 也一律輸出大寫;解碼時大小寫都吃。唯一要小心的地方是簽章與快取鍵:如果某個環節是直接對編碼後的字串做雜湊或比字串,大小寫不同就會被判定成兩個不同的值。
網址裡的中文可以不編碼嗎?瀏覽器好像看得懂。
瀏覽器網址列會把中文顯示出來,但實際發出請求時仍然送的是編碼後的位元組——那只是顯示層的美化。你自己在程式裡拼字串、寫 HTTP client 或設定 redirect 時沒有這層保護,未編碼的非 ASCII 字元可能被中間的 proxy、CDN 或 WAF 拒絕,或用錯誤的編碼猜測去解讀。要放進 URL 的非 ASCII 內容一律先編碼。
這跟 Base64 編碼差在哪?兩個都叫「編碼」。
目的完全不同。百分比編碼是為了避開 URL 語法裡有特殊意義的字元,結果人類還讀得懂大半,長度只有需要跳脫的部分會變長。Base64 是把任意二進位資料表示成 64 個安全字元,結果完全不可讀且固定膨脹約 33%。要把一段文字放進 query string 用百分比編碼;要把圖片或二進位檔塞進文字欄位用 Base64。兩者都不是加密,不提供任何保密性。