URL 的最佳網站格式,是在正確的作用範圍中套用百分比編碼,因為網址只能承載有限的一組字元,而每一個不安全的位元組都必須在瀏覽器、伺服器與 API 之間傳遞之前先進行跳脫。百分比編碼會將 URL 中不安全的每個字元,替換成一個百分比符號加上其各個位元組的兩位數十六進位值,因此一個空格會變成 %20,一個表情符號則會變成四組百分比符號,共同代表原始的多位元組 UTF-8 序列。實務上有兩個作用範圍很重要:URL 元件,也就是單一查詢值或路徑片段,必須跳脫每一個保留字元;以及完整 URL,必須保留其結構字元(例如冒號、斜線、問號與井字號)的完整性,只跳脫真正不安全的部分。在這兩個作用範圍之間做出選擇,就是最佳網站格式背後的核心決策。這個選擇會改變哪些字元會被跳脫,進而改變產生的網址在接收端是否仍然能被正確解析。

URL 格式決策實際如何運作
網址並不是自由格式的文字。定義 URI 中允許哪些字元的標準是 RFC 3986,它在「可直接出現的非保留字元」與「保留字元」之間畫了一條明確的界線:保留字元可能會分隔網址的各個部分,或者在作為資料出現時必須被跳脫。非保留字元集包括十個 ASCII 字母、十個數字、連字號、句號、底線與波浪號。其他所有字元都落在這條線的另一側,在傳遞之前都需要先做決定。
當有人搜尋最佳網站格式時,他們通常指的是以下兩個具體含意中的一個。第一個是即將放入 URL 中的單一值的格式,例如搜尋詞、使用者名稱、檔案名稱或回呼網址,其中值內出現的任何保留字元都必須被跳脫,否則會被誤認為分隔符號。第二個是需要整理或放進另一個參數中的完整 URL 的格式,其中結構字元應該被保留,只有真正不安全的字元才應該被跳脫。
對這兩種工作使用同一個編碼器,是損壞連結最常見的來源。將完整網址當成單一元件進行編碼,會剝掉通訊協定與路徑分隔符號,讓接收端的解析器拿到一個無法讀取的內容。將單一查詢值當成完整網址進行編碼,則會讓 & 號與等號保持未編碼狀態,使得該值悄悄地被切成兩個參數而非一個。解決方法是先選定作用範圍,再執行編碼器。
元件模式 vs 完整 URL 模式
這兩個作用範圍並不能互換。元件模式將輸入視為 URL 的一部分,會跳脫每一個保留字元,使該值絕不會被誤認為分隔符號,包括 & 號、等號、斜線、問號與井字號。它還會跳脫標準中列為子分隔符號的一小組額外字元,部分伺服器、簽章機制或分析平台會特別處理這些字元:驚嘆號、撇號、括號與星號。元件模式的輸出是嚴格且可攜的。將其放入任何查詢值或路徑片段中,周圍的網址仍然可以正確解析,無論由哪個框架接收都一樣。
完整 URL 模式將輸入視為一個完整的網址,會保留將其串接在一起的結構字元,也就是冒號、斜線、問號與井字號,同時仍然跳脫不安全的字元,例如空格與非 ASCII 字母。當你想要清理別人貼上的、含有雜散空格或原始中文字元的網址時,或者當你需要把完整的回呼網址放進另一個參數中(例如 OAuth 的 redirect_uri 或 webhook 目標)時,這是正確的模式。
兩種模式都會先將文字編碼為 UTF-8,因此多位元組字元會以正確數量的百分比組合呈現。中文的「你好」會以六組百分比往返呈現,表情符號以四組往返,附加腔調的拉丁字母以兩組往返。不會有任何悄悄的損壞,這正是大多數臨時轉換器最容易出錯的地方。
如何正確格式化 URL
- 選擇作用範圍。對於將放入較大網址中的單一查詢值、路徑片段或片段識別碼,請選擇 URL 元件。當你想要整理一個完整連結或將其放進另一個參數中時,請選擇完整 URL。
- 選擇方向。使用「編碼」將可讀文字轉成可安全放入 URL 的百分比編碼輸出。使用「解碼」將百分比編碼文字還原為原始發送者所指的易懂字元。
- 將文字貼入輸入框中。當你輸入時,結果會即時更新;如果輸入格式錯誤——例如多餘的百分比符號、%zz,或被截斷的多位元組序列——工具會停止動作並顯示清楚的錯誤,而不是回傳一個損壞的字串。請修正來源後再試一次。
- 點擊「複製」將編碼或解碼結果放到你的剪貼簿,然後貼到 URL 欄位、API 請求、重導向設定或程式碼中它該出現的位置。
透過 URL 解碼器 執行這四個步驟,可讓決策在每個階段都保持可見,因此你隨時都能知道是哪個作用範圍與哪個方向產生了即將送出的輸出。
將格式與工作對應起來
| 工作 | 範圍 | 方向 | 原因 |
|---|---|---|---|
| 將搜尋詞放入查詢字串中 | URL 元件 | 編碼 | 詞中的空格、& 號與等號若未編碼,會將它拆成額外的參數。 |
| 建立 OAuth 的 redirect_uri | 完整 URL | 編碼 | 通訊協定、斜線與查詢分隔符號必須保留下來,才能讓接收伺服器解析回呼。 |
| 讀取別人分享的連結 | 完整 URL | 解碼 | 百分比組合藏起了人類友善的文字;解碼後會還原原始的搜尋詞或追蹤標籤。 |
| 在分析儀表板中稽核追蹤參數 | 完整 URL | 解碼 | utm_source、utm_campaign 與類似的值通常以百分比編碼送達;解碼能呈現實際被衡量的內容。 |
| 將回呼網址作為查詢值傳入另一個 URL 中 | URL 元件 | 編碼 | 在這裡內部網址是資料,因此其保留字元必須被跳脫,否則外部網址會損壞。 |
| 清理複製連結中的雜散空格 | 完整 URL | 編碼 | 只有空格與非 ASCII 位元組是不安全的;網址的結構字元會保持完整。 |
將此表當作快速參考,然後把任何邊界案例丟進工具中確認。邊界案例——例如路徑片段中含有 & 號的值,或本身含有問號的回呼 URL——幾乎總是回到同一條規則:作用範圍決定了哪些字元會被跳脫。
會破壞真實 URL 的格式錯誤
大多數損壞的連結與悄悄的資料損毀,都來自一小組格式錯誤。將完整網址編碼成元件,會剝掉通訊協定並把可運作的連結變成瀏覽器解讀為另一個頁面的相對路徑。將單一值編碼成完整 URL,則會讓 & 號保持未編碼,因此像「cats & dogs」這樣的搜尋詞會悄悄變成兩個參數。編碼兩次——一次在程式碼中,一次在記錄層中——會產生像 %2520 這樣的字串,接收伺服器只解碼一次,結果在資料中留下字面的 %20。
解碼也有自己的失敗模式。字串末端出現多餘的百分比符號、百分比後接著不是合法十六進位數字的字元(例如 %zz),或被從中截斷的多位元組序列,都會產生格式錯誤的輸入。在這些情況下,正確的行為是停下來並顯示錯誤,才能找出錯誤資料的來源。一個會悄悄回傳損壞字串的解碼器,比拒絕執行的解碼器更難除錯,這就是為什麼 URL 解碼器會明確回報格式錯誤的百分比組合,而不是嘗試修補它們。
Unicode 處理是第三種失敗模式。沒有先把字元轉成 UTF-8 位元組就一個一個編碼的工具,會產生伺服器無法解碼回同一字元的百分比組合。CJK 文字與表情符號是常見的受害者,因為它們的碼點佔用超過一個位元組,且位元組順序很重要。先以 UTF-8 編碼(這是 RFC 3986 對現代資料的要求),能使往返過程可預期。
為什麼格式檢查會在瀏覽器中本機執行
URL 經常承載人們不希望離開其裝置的內容:回呼參數中的 API 金鑰、共用連結中的工作階段權杖、內部主機名、支援工單中的客戶識別碼,以及會揭露預備環境的網址。透過遠端服務對這些值進行編碼或解碼,等於將輸入內容交給該服務信任。以純 JavaScript 在本機執行編碼與解碼(如同 URL 解碼器的做法),可以讓位元組留在產生它們的同一台機器上。該工具在頁面載入後仍可持續運作,因此在飛機上或嚴格的防火牆後也能使用。
本機處理的另一個實際好處是,錯誤訊息是由產生編碼輸出的同一段程式碼所產生。當工具指出百分比序列格式錯誤時,產生該錯誤的同一條 UTF-8 路徑,就是會產生修正的路徑,這讓從損壞輸入到可運作網址的循環變得短到可以在程式碼審查期間執行。
如果你正在權衡各種選項,HMAC 產生器:命令列 vs 線上工具——如何挑選對此有詳細說明。
如果你正在權衡各種選項,摩斯密碼翻譯器:命令列 vs 線上工具對此有詳細說明。