使用 网址SearchParams 轻松操控网址

Eric Bidelman

URLSearchParams API 为网址的各个部分提供一致的接口,并允许对查询字符串(? 之后的内容)进行细微的操纵。

传统上,开发者使用正则表达式和字符串拆分从网址中提取查询参数。如果我们都对自己真诚,那就没意思了。 此过程可能非常繁琐,并且容易出错。我有一个秘诀是,在多个大型 Google.com 应用(包括 Google 追踪圣诞老人2015 年 Google I/O 大会网站)中重复使用了相同的 get|set|removeURLParameter 辅助方法

是时候打造合适的 API 为我们完成这项工作了!

网址SearchParams 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);
}

set 参数值:

params.set('version', 2);

为现有参数append另一个值:

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

删除参数:

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(...)

虽然 URLSearchParams 尚未在 Chrome 中实现,但还可以与 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 的 Material Design Iconset Generator。我用它来设置应用的深层链接的初始状态。非常方便 :)