使用 URLSearchParams 輕鬆操控網址

Eric Bidelman

URLSearchParams API 可為網址的位元和部分提供一致的介面,並對查詢字串 (? 之後的內容) 進行簡單的操控。

一般來說,開發人員會使用規則運算式和字串分割功能,從網址提取查詢參數。如果你對我們自己都誠心,就不會很有趣。 不但繁瑣,容易出錯。我其中一個暗秘密是,我在數個大型 Google.com 應用程式中重複使用了相同的 get|set|removeURLParameter 輔助方法,包括 Google 聖誕老人追蹤器Google I/O 2015 網路

該使用適當的 API 來為我們完成這項工作!

URLSearchParams API

立即試用

Chrome 49 版則是根據網址規格實作 URLSearchParams,這個 API 適合用於設定網址查詢參數。我認為 URLSearchParams 與網址等同於 FormData 的便利性。

那麼,如何運用這些資料?只要輸入網址字串,就能輕鬆擷取參數值:

// Can also constructor from another URLSearchParams
const params = new URLSearchParams('q=search+string&version=1&person=Eric');

params.get('q') === "search string"
params.get('version') === "1"
Array.from(params).length === 3
for (let p of params) {
    console.log(p);
}

設定參數值:

params.set('version', 2);

append現有參數的其他值:

params.append('person', 'Tim');
params.getAll('person') === ['Eric', 'Tim']

delete 參數:

params.delete('person');

使用網址

在大多數情況下,您或許會使用完整網址或修改應用程式網址。在下列情況中,URL 建構函式特別實用:

const url = new URL('https://example.com?foo=1&bar=2');
const params = new URLSearchParams(url.search);
params.set('baz', 3);

params.has('baz') === true
params.toString() === 'foo=1&bar=2&baz=3'

如要實際變更網址,您可以擷取參數並更新參數值,然後使用 history.replaceState 更新網址。

// URL: https://example.com?version=1.0
const params = new URLSearchParams(location.search);
params.set('version', 2.0);

window.history.replaceState({}, '', `${location.pathname}?${params}`);
// URL: https://example.com?version=2.0

在這裡,我已使用 ES6 範本字串,從應用程式的現有網址路徑和修改過的參數重新建構更新後的網址。

用於與其他地點網址整合

根據預設,在 fetch() API 要求中傳送 FormData 時,系統會建立多部分主體。如果需要,URLSearchParams 會提供替代機制給經過網址編碼 (而非 mime 多部分) 的 POST 資料。

const params = new URLSearchParams();
params.append('api_key', '1234567890');

fetch('https://example.com/api', {
    method: 'POST',
    body: params
}).then(...)

雖然 Chrome 尚未導入這項功能,但 URLSearchParams 也能與 URL 建構函式和 a 標記整合。兩者都提供唯讀屬性 .searchParams 來存取查詢參數,藉此支援我們的新夥伴:

const url = new URL(location);
const foo = url.searchParams.get('foo') || 'somedefault';

連結也會取得 .searchParams 屬性:

const a = document.createElement('a');
a.href = 'https://example.com?filter=api';

// a.searchParams.get('filter') === 'api';

功能偵測和瀏覽器支援

Chrome 49、Firefox 44 和 Opera 36 目前支援 URLSearchParams

if ('URLSearchParams' in window) {
    // Browser supports URLSearchParams
}

如果是 polyfill,建議使用 github.com/WebReflection/url-search-params 所列的參數。

示範

立即試用範例

如要在實際應用程式中查看 URLSearchParams,請參閱 Polymer 的質感設計圖示集產生器。我已將其用於設定應用程式的深層連結初始狀態。相當方便 :)