encodeURI()

Baseline 已廣泛支援

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

encodeURI() 函式透過將某些字元的每個例項替換為一個、兩個、三個或四個表示該字元 UTF-8 編碼的轉義序列來編碼 URI(對於由兩個代理字元組成的字元,將只有四個轉義序列)。與 encodeURIComponent() 相比,此函式編碼的字元較少,保留了作為 URI 語法一部分的字元。

試一試

const uri = "https://mozilla.org/?x=шеллы";
const encoded = encodeURI(uri);
console.log(encoded);
// Expected output: "https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"

try {
  console.log(decodeURI(encoded));
  // Expected output: "https://mozilla.org/?x=шеллы"
} catch (e) {
  // Catches a malformed URI
  console.error(e);
}

語法

js
encodeURI(uri)

引數

uri

要編碼為 URI 的字串。

返回值

一個新字串,表示作為 URI 編碼的所提供字串。

異常

URIError

如果 uri 包含孤立代理則丟擲錯誤。

描述

encodeURI() 是全域性物件的函式屬性。

encodeURI() 函式透過 UTF-8 程式碼單元跳脫字元,每個八位位元組以 %XX 格式編碼,必要時用 0 左填充。由於 UTF-16 中的孤立代理不編碼任何有效的 Unicode 字元,它們會導致 encodeURI() 丟擲 URIError

encodeURI() 轉義所有字元除了

A–Z a–z 0–9 - _ . ! ~ * ' ( )

; / ? : @ & = + $ , #

第二行中的字元是可能屬於 URI 語法的字元,並且僅由 encodeURIComponent() 進行轉義。encodeURI()encodeURIComponent() 都不編碼字元 -.!~*'(),這些字元被稱為“非保留標記”,它們沒有保留用途,但允許在 URI 中“原樣”存在。(參見 RFC2396

encodeURI() 函式不編碼對 URI 具有特殊含義(保留字元)的字元。以下示例顯示了 URI 可能包含的所有部分。請注意某些字元如何用於表示特殊含義

url
http://username:password@www.example.com:80/path/to/file.php?foo=316&bar=this+has+spaces#anchor

encodeURI,顧名思義,用於將整個 URL 編碼,假設它已經格式良好。如果你想將字串值動態組裝成一個 URL,你可能需要對每個動態段使用 encodeURIComponent(),以避免在不需要的地方出現 URL 語法字元。

js
const name = "Ben & Jerry's";

// This is bad:
const link = encodeURI(`https://example.com/?choice=${name}`); // "https://example.com/?choice=Ben%20&%20Jerry's"
console.log([...new URL(link).searchParams]); // [['choice', 'Ben '], [" Jerry's", '']

// Instead:
const link = encodeURI(
  `https://example.com/?choice=${encodeURIComponent(name)}`,
);
// "https://example.com/?choice=Ben%2520%2526%2520Jerry's"
console.log([...new URL(link).searchParams]); // [['choice', "Ben%20%26%20Jerry's"]]

示例

encodeURI() vs. encodeURIComponent()

encodeURI()encodeURIComponent() 的區別如下

js
const set1 = ";/?:@&=+$,#"; // Reserved Characters
const set2 = "-.!~*'()"; // Unreserved Marks
const set3 = "ABC abc 123"; // Alphanumeric Characters + Space

console.log(encodeURI(set1)); // ;/?:@&=+$,#
console.log(encodeURI(set2)); // -.!~*'()
console.log(encodeURI(set3)); // ABC%20abc%20123 (the space gets encoded as %20)

console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24%23
console.log(encodeURIComponent(set2)); // -.!~*'()
console.log(encodeURIComponent(set3)); // ABC%20abc%20123 (the space gets encoded as %20)

編碼孤立代理會丟擲錯誤

如果嘗試編碼不屬於高低位對的代理,將丟擲 URIError。例如

js
// High-low pair OK
encodeURI("\uD800\uDFFF"); // "%F0%90%8F%BF"

// Lone high-surrogate code unit throws "URIError: malformed URI sequence"
encodeURI("\uD800");

// Lone low-surrogate code unit throws "URIError: malformed URI sequence"
encodeURI("\uDFFF");

你可以使用 String.prototype.toWellFormed() 替換孤立代理為 Unicode 替換字元 (U+FFFD),以避免此錯誤。你也可以使用 String.prototype.isWellFormed() 在將字串傳遞給 encodeURI() 之前檢查它是否包含孤立代理。

RFC3986 編碼

最新的 RFC3986 將方括號保留(用於 IPv6),因此在形成可能作為 URL 一部分的內容(例如主機)時不會被編碼。它還保留了 !、'、(、) 和 *,儘管這些字元沒有正式的 URI 分隔用途。以下函式用於對符合 RFC3986 的 URL 格式的字串進行編碼。

js
function encodeRFC3986URI(str) {
  return encodeURI(str)
    .replace(/%5B/g, "[")
    .replace(/%5D/g, "]")
    .replace(
      /[!'()*]/g,
      (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`,
    );
}

規範

規範
ECMAScript® 2026 語言規範
# sec-encodeuri-uri

瀏覽器相容性

另見