Простая манипуляция URL-адресами с помощью URLSearchParams

API URLSearchParams обеспечивает согласованный интерфейс для отдельных частей URL-адреса и позволяет выполнять тривиальные манипуляции со строкой запроса (то, что после ? ).

Традиционно разработчики используют регулярные выражения и разбиение строк для извлечения параметров запроса из URL-адреса. Если мы все честны сами с собой, это невесело. Это может быть утомительно и чревато ошибками. Один из моих темных секретов заключается в том, что я повторно использовал одни и те же вспомогательные методы get|set|removeURLParameter в нескольких крупных приложениях Google.com, включая Google Santa Tracker и веб-сайт Google I/O 2015 .

Пришло время создать правильный API, который сделает это за нас!

URLSearchParams API

Попробуйте демо

Chrome 49 реализует URLSearchParams из спецификации URL — API, который полезен для работы с параметрами URL-запроса. Я считаю URLSearchParams таким же удобным средством для URL-адресов, как FormData для форм.

Так что же с этим можно сделать? Имея строку URL-адреса, вы можете легко извлечь значения параметров:

// 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);

добавьте другое значение для существующего параметра:

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

удалить параметр(ы):

params.delete('person');

Работа с URL-адресами

Большую часть времени вы, вероятно, будете работать с полными URL-адресами или изменять URL-адрес своего приложения. Конструктор 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'

Чтобы внести фактические изменения в URL-адрес, вы можете получить параметры, обновить их значения, а затем использовать history.replaceState для обновления URL-адреса.

// 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 для восстановления обновленного URL-адреса из существующего пути URL-адреса приложения и измененных параметров.

Интеграция с другими местами, где используются URL-адреса.

По умолчанию отправка FormData в запросе API fetch() создает составное тело. Если вам это нужно, URLSearchParams предоставляет альтернативный механизм данным POST, которые закодированы в urlencode, а не состоят из нескольких частей mime.

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
}

Для полифилов я рекомендую вариант на github.com/WebReflection/url-search-params .

Демо

Попробуйте образец !

Чтобы увидеть URLSearchParams в реальном приложении, воспользуйтесь генератором Iconset Generator для дизайна материалов Polymer . Я использовал его для настройки исходного состояния приложения по глубокой ссылке . Довольно удобно :)