網址裡出現空格、&、中文,瀏覽器常常會看不懂——就像信封地址寫「3 樓 & 4 樓」,郵差可能以為你要寄兩戶。JavaScript 有兩個長得很像的函式:encodeURI 和 encodeURIComponent。名字只差一個 Component,但用錯的後果,有時比咖啡潑在鍵盤上還難收拾。
**一句話答案:**要編碼「整條網址」用 encodeURI;要編碼「網址裡某一塊的值」(查詢參數、路徑片段)用 encodeURIComponent。不確定時,參數值幾乎永遠選後者。
目錄
encodeURI 和 encodeURIComponent 差在哪?
想像你在寫地址:
encodeURI:整條地址一起處理,但會保留: / ? & #這些「路標」——它們是網址結構的一部分,不能亂改。encodeURIComponent:只處理「包裹裡的內容」,把&、=、/等特殊字元全部轉成%XX,避免破壞外層網址結構。
| 比較項目 | encodeURI | encodeURIComponent |
|---|---|---|
| 編碼對象 | 完整 URI | 單一 URI 組件(參數值、路徑段等) |
| 轉義範圍 | 只轉「不該出現在 URI 裡」的字元 | 轉義幾乎所有在 URI 有特殊意義的字元 |
| 會保留的字元 | :、/、?、&、# 等結構符號 | 無(結構符號也會被編碼) |
| 典型用途 | 整條網址字串需要編碼時 | 查詢參數的值、路徑片段、要嵌進 URL 的字串 |
encodeURI 是什麼時候用的?
encodeURI 適合處理已經長得像完整網址的字串,例如使用者輸入的 URL 裡有空格或中文,你要讓它變成合法 URI,但不想把 https:// 裡的 : 和 / 也編掉。
encodeURI("https://www.example.com/my page?name=John Doe");
// "https://www.example.com/my%20page?name=John%20Doe"空格變成 %20,但 ?、= 還在——因為它們是查詢字串的結構。問題也出在這裡:如果 name 的值本身含有 & 或 =,encodeURI 不會幫你保護這些字元,伺服器可能會誤讀參數。
encodeURIComponent 是什麼時候用的?
encodeURIComponent 把一段文字當成「要塞進網址某個位置的值」,所以特殊字元一律編碼,避免跟網址語法打架。
encodeURIComponent("name=John Doe&age=30");
// "name%3DJohn%20Doe%26age%3D30"= 變 %3D,& 變 %26,空格變 %20。這就是為什麼組查詢字串時,每個參數的值都應該各自包一層 encodeURIComponent。
實戰:組查詢字串該怎麼寫?
下面用同一組資料示範兩種寫法:
const name = "John Doe";
const age = 30;
const url = "https://www.example.com/search";
// 方法一:整段丟進 encodeURI(查詢參數不推薦)
const badUrl = encodeURI(`${url}?name=${name}&age=${age}`);
// "https://www.example.com/search?name=John%20Doe&age=30"
// 簡單案例看起來沒事,但 name 若含 & 就會炸
// 方法二:只對參數值 encodeURIComponent(推薦)
const goodUrl = `${url}?name=${encodeURIComponent(name)}&age=${encodeURIComponent(age)}`;
// "https://www.example.com/search?name=John%20Doe&age=30"兩種寫法在 name = "John Doe" 時結果一樣。差別在「值裡有沒有特殊字元」:
const tricky = "John & Jane";
encodeURI(`${url}?name=${tricky}`);
// "https://www.example.com/search?name=John%20&%20Jane"
// & 沒被編碼 → 伺服器可能以為有兩個參數
`${url}?name=${encodeURIComponent(tricky)}`;
// "https://www.example.com/search?name=John%20%26%20Jane"
// & 變 %26 → 安全現代專案也可以直接用 URLSearchParams,它會幫你處理編碼,少手動拼接:
const params = new URLSearchParams({ name: tricky, age: String(age) });
const safeUrl = `${url}?${params}`;
// "https://www.example.com/search?name=John+%26+Jane&age=30"+ 和 %20 在查詢字串裡語意相近;重點是特殊字元不會再破壞結構。
常見踩雷:什麼時候會用錯?
- 用
encodeURI包查詢參數的值:參數含&、=、#時,網址可能被截斷或解析錯誤。 - 對整條網址用
encodeURIComponent:https://會變成https%3A%2F%2F,瀏覽器打不開。 - 重複編碼:已經
%20的字串再 encode 一次,會變%2520,搜尋或導頁就對不上。 - 忘記解碼:讀取時用
decodeURIComponent還原;URLSearchParams.get()會自動解碼。
快速決策:我現在該用哪個?
| 情境 | 用哪個 |
|---|---|
| 整條 URL 有空格或中文,但結構已正確 | encodeURI |
| 查詢參數的 key 或 value | encodeURIComponent(或 URLSearchParams) |
路徑片段(例如 /users/王小明 裡的名字) | encodeURIComponent |
要把一段文字嵌進 ?q= 後面 | encodeURIComponent |
| 不確定 | 參數值 → encodeURIComponent;整條 URL → encodeURI |
網址編碼這件事,本質就是「哪些字元是地址本身,哪些只是包裹裡的內容」。記住這個分工,encodeURI 和 encodeURIComponent 就不會再讓你半夜 debug 404 了——除非你真的把咖啡打翻在鍵盤上,那 AI 也救不了。
參考資料
- encodeURI() — MDN:
encodeURI保留與不保留的字元清單 - encodeURIComponent() — MDN:
encodeURIComponent行為與範例 - URLSearchParams — MDN:現代瀏覽器組查詢字串的建議做法
- RFC 3986 — URI Generic Syntax:URI 字元集與 percent-encoding 的規格來源

