Как получить GET-параметры из URL в JavaScript

Чтобы получить GET-параметры из URL в JavaScript, создайте URLSearchParams из location.search. Так вы прочитаете параметры строки запроса: один ключ, все значения и повторяющиеся пары. Затем вы сможете изменить адрес без перезагрузки.

Как получить параметр из URL в JavaScript

Возьмите строку запроса текущей страницы через location.search. Передайте ее конструктору URLSearchParams и вызовите get().

const params = new URLSearchParams(location.search);
const user = params.get('user') ?? 'гость';

console.log(user);

Для адреса https://example.com/?user=Анна консоль покажет Анна. Если ключ отсутствует, get() вернет null, а оператор ?? подставит «гость».

Пустое значение отличается от отсутствующего ключа.

const params = new URLSearchParams(location.search);
const page = params.get('page') ?? '1';

console.log(page);

На странице https://example.com/catalog переменная page получит строку 1. Адрес https://example.com/catalog?page= даст пустую строку, потому что ключ существует.

Как устроена строка GET-параметров

Query-строка начинается после ? и заканчивается перед #. Символ & разделяет пары, а = отделяет имя параметра от значения.

https://example.com/catalog?category=books&page=2#reviews
  • Путь. /catalog указывает страницу.
  • Параметры. category=books&page=2 содержит две пары.
  • Хэш. #reviews указывает фрагмент документа.

location.search возвращает query-строку вместе со знаком ?. location.href содержит полный адрес: протокол, хост, путь, параметры и хэш.

Для GET-параметров берите location.search. Если передать в URLSearchParams весь location.href, объект получит лишние части адреса.

Значения с кириллицей, пробелами и символами & нужно передавать через API URL. Объект сам выполнит нужное кодирование при сборке строки.

Одно значение, все параметры и повторяющиеся ключи

Метод get() читает первое значение, has() проверяет ключ, а getAll() возвращает повторяющиеся значения. Для уникальных ключей пары можно превратить в объект.

Методы URLSearchParams

Полный справочник находится в документации URLSearchParams на MDN. Свойство size читают без скобок.

Метод или свойствоЧто делаетЧто возвращает
get(name)Читает первое значение ключаСтроку или null
getAll(name)Читает все значения ключаМассив строк
has(name)Проверяет наличие ключаtrue или false
has(name, value)Проверяет имя и значение парыtrue или false
set(name, value)Заменяет все значения ключаundefined
append(name, value)Добавляет еще одну паруundefined
delete(name)Удаляет ключ и его значенияundefined
entries()Возвращает итератор парИтератор
forEach(callback)Вызывает функцию для каждой парыundefined
sizeСчитает все пары, включая повторыЧисло
sort()Сортирует пары по именам ключейundefined
toString()Собирает query-строкуСтроку без ?

Чтение одного и нескольких значений

Используйте has(), когда пустое значение нужно отличить от отсутствующего ключа.

const params = new URLSearchParams('?mode=dark&empty=');
const mode = params.get('mode');
const hasEmpty = params.has('empty');
const hasDark = params.has('mode', 'dark');
const missing = params.get('page') ?? '1';

console.log(mode, hasEmpty, hasDark, missing);

Строка ?mode=dark&empty= даст вывод dark true true 1. Параметр empty существует, хотя его значение пустое.

Повторяющийся ключ читайте через getAll().

const params = new URLSearchParams('?tag=js&tag=web');
const firstTag = params.get('tag');
const tags = params.getAll('tag');

console.log(firstTag);
console.log(tags);

Код выведет js и массив ['js', 'web']. Метод get() прочитает только первое значение.

Объект из всех параметров

Передайте объект параметров в Object.fromEntries(), когда каждый ключ встречается один раз.

const params = new URLSearchParams('?page=2&sort=price');
const query = Object.fromEntries(params);

for (const [name, value] of Object.entries(query)) {
  console.log(name, value);
}

console.log(query);

Для адреса https://example.com/?page=2&sort=price цикл выведет page 2 и sort price. Объект будет выглядеть так: { page: '2', sort: 'price' }.

При повторяющемся ключе Object.fromEntries() оставит последнее значение. Для массивов используйте getAll().

Как разобрать произвольный адрес

Создайте объект URL, если адрес не связан с текущей страницей. Свойство search хранит query-строку, searchParams дает методы чтения, а hash содержит фрагмент вместе со знаком #.

const address = new URL('https://example.com/products?sku=42#details');

console.log(address.search);
console.log(address.searchParams.get('sku'));
console.log(address.hash);

Код выведет ?sku=42, затем 42, затем #details.

Относительный адрес требует базового URL.

const address = new URL('/catalog?page=3', 'https://example.com');
const page = address.searchParams.get('page');

console.log(address.href);
console.log(page);

Конструктор дополнит путь до https://example.com/catalog?page=3, а get() вернет строку 3. Такой прием подходит для ссылок без протокола и домена.

В Node.js глобальные URL и URLSearchParams доступны в серверном коде. Те же API также входят во встроенный модуль node:url.

Параметры после hash в SPA

SPA часто хранит состояние маршрута после символа #. Если хэш состоит из пар, удалите первый символ и передайте остаток конструктору.

const hashParams = new URLSearchParams(location.hash.slice(1));
const section = hashParams.get('section') ?? 'home';

console.log(section);

По адресу https://example.com/#section=contacts переменная section получит contacts.

Маршрут вида #/catalog?sort=price нужно разобрать как относительный URL.

const hashUrl = new URL(location.hash.slice(1), location.origin);
const sort = hashUrl.searchParams.get('sort') ?? 'name';

console.log(sort);

Для адреса https://example.com/#/catalog?sort=price код выведет price.

Как изменить параметры и обновить адрес без перезагрузки

Изменяйте объект URL методами set(), append() и delete(). Затем передайте готовый адрес в history.replaceState() или history.pushState().

const url = new URL(location.href);

url.searchParams.set('page', '2');
url.searchParams.append('tag', 'javascript');
url.searchParams.delete('draft');

history.replaceState(null, '', url);
console.log(url.href);

Исходный адрес https://example.com/catalog?page=1&draft=true сменится на https://example.com/catalog?page=2&tag=javascript. Документ останется открытым, а адрес изменится.

Метод replaceState() заменяет текущую запись истории. Берите его для фильтров, когда кнопка «Назад» не должна возвращать каждое промежуточное состояние.

pushState() добавляет новую запись. Используйте его для состояний, к которым пользователь должен вернуться кнопкой «Назад».

const url = new URL(location.href);
url.searchParams.set('view', 'grid');

history.pushState(null, '', url);
console.log(location.search);

Если открыть https://example.com/catalog и выполнить код, консоль покажет ?view=grid. Страница не перезагрузится.

History API меняет адрес только в пределах текущего источника. Само изменение URL не обновляет интерфейс, поэтому состояние страницы меняйте отдельным кодом.

Метод sort() упорядочивает пары по именам ключей, а toString() собирает строку без знака ?.

const params = new URLSearchParams('?z=1&a=2');
params.sort();

console.log(params.toString());

Результат будет a=2&z=1. Если адрес нужен для ссылки, добавьте знак ? самостоятельно.

Для перехода на другой документ используйте перенаправление, а не History API. Примеры собраны в статье о перенаправлении через JavaScript.

Подготовка URL для fetch

Соберите параметры через URLSearchParams, а затем добавьте их к адресу API.

const params = new URLSearchParams();
params.set('q', 'кириллица & пробел');
params.set('page', '2');

const requestUrl = `https://api.example.com/search?${params}`;
console.log(requestUrl);

Консоль покажет https://api.example.com/search?q=%D0%BA%D0%B8%D1%80%D0%B8%D0%BB%D0%BB%D0%B8%D1%86%D0%B0+%26+%D0%BF%D1%80%D0%BE%D0%B1%D0%B5%D0%BB&page=2. Адрес служит примером и не выполняет сетевой запрос.

const url = new URL('/api/search', location.href);
url.searchParams.set('q', 'javascript');
url.searchParams.set('page', '2');

const response = await fetch(url);
const data = await response.json();

console.log(data);

На странице https://example.com/catalog запрос уйдет на https://example.com/api/search?q=javascript&page=2. Сервер должен вернуть JSON, иначе вызов response.json() завершится ошибкой.

Как кодировать значения параметров

При чтении query-строки URLSearchParams превращает знак + в пробел. При сборке строки объект записывает пробел как +.

const params = new URLSearchParams('?name=Иван+Петров&note=a%26b');

console.log(params.get('name'));
console.log(params.get('note'));
console.log(params.toString());

Код выведет Иван Петров и a&b. Метод toString() вернет закодированную строку.

encodeURIComponent() кодирует отдельное значение. encodeURI() сохраняет знаки структуры адреса, поэтому он подходит для полного URL, но не для отдельной пары.

const value = 'a&b = тест';
const encoded = encodeURIComponent(value);
const url = `https://example.com/?q=${encoded}`;

console.log(url);

Символы &, пробел и = попадут в URL как кодированные последовательности. Они не разделят query-строку на лишние пары.

При работе с URLSearchParams передавайте исходные значения без предварительного кодирования.

const params = new URLSearchParams();
params.set('q', 'кириллица & пробел');

const url = `https://example.com/search?${params}`;
console.log(url);

Получится адрес https://example.com/search?q=%D0%BA%D0%B8%D1%80%D0%B8%D0%BB%D0%BB%D0%B8%D1%86%D0%B0+%26+%D0%BF%D1%80%D0%BE%D0%B1%D0%B5%D0%BB. Повторное кодирование превратит знак % в часть нового значения.

Буквальный плюс передавайте через set() или append().

const params = new URLSearchParams();
params.set('value', 'a+b');

console.log(params.toString());
console.log(params.get('value'));

Консоль покажет value=a%2Bb и a+b. После get() дополнительный decodeURIComponent() не нужен.

Числа, флаги и массивы в параметрах

Все значения приходят строками. После чтения приведите их к нужному типу и проверьте допустимый диапазон.

const params = new URLSearchParams('?page=3&debug=true');
const page = Number.parseInt(params.get('page') ?? '1', 10);
const debug = params.get('debug') === 'true';

console.log(page, debug);

Код выведет число 3 и значение true. Строка false даст false при таком явном сравнении.

Для строгой проверки целого положительного числа сначала проверьте всю строку.

const params = new URLSearchParams('?limit=abc');
const rawLimit = params.get('limit') ?? '20';
const candidate = /^[0-9]+$/.test(rawLimit) ? Number(rawLimit) : NaN;
const limit = Number.isSafeInteger(candidate) && candidate > 0
  ? candidate
  : 20;

console.log(limit);

Значение abc в строке ?limit=abc не пройдет проверку, поэтому код выведет 20. Такая проверка также отклонит 3abc, пустую строку и отрицательное число.

Массив передавайте повторяющимися ключами или соглашением с квадратными скобками. Важно выбрать один формат для всего проекта.

const params = new URLSearchParams('?ids[]=10&ids[]=20');
const ids = params.getAll('ids[]').map((value) => Number(value));

console.log(ids);

Массив ids будет содержать числа [10, 20]. В формате ?id=10&id=20 ключом для getAll() будет id. Квадратные скобки входят в имя ключа и не получают особого смысла.

Проверьте отдельно отсутствующий и пустой ключ.

const params = new URLSearchParams(location.search);
const query = params.get('q');

if (query === null) {
  console.log('ключ отсутствует');
} else if (query === '') {
  console.log('значение пустое');
} else {
  console.log(query);
}

Для адреса без q код выведет «ключ отсутствует». Для адреса ?q= он выведет «значение пустое».

Ошибки при ручном разборе GET-параметров

Ручной парсер через split() теряет декодирование и повторяющиеся значения. Он также ломается на знаке = внутри значения.

const raw = location.search.slice(1);
const pairs = raw.split('&');
const result = {};

for (const pair of pairs) {
  const parts = pair.split('=');
  result[parts[0]] = parts[1];
}

console.log(result);

Для адреса ?note=a=b такой код сохранит только { note: 'a' }. Он также оставит кодированную кириллицу без расшифровки и потеряет повторные значения.

Используйте URLSearchParams, если строка может содержать специальные символы или одинаковые ключи.

Не выделяйте query-строку из location.href вручную. Хэш попадет в последнее значение, если код не остановится перед символом #. Свойство location.search уже отделяет query-строку от фрагмента.

Не используйте for...in для массива. Цикл проходит по именам свойств, поэтому для элементов массива берите for...of, а для параметров – entries() или forEach().

Метод substr() помечен в документации MDN как устаревший. Для части строки используйте slice(), но query-строку лучше сразу передать в URLSearchParams.

Параметр из адреса контролирует пользователь. Выводите его через textContent, а не через innerHTML.

const params = new URLSearchParams(location.search);
const message = params.get('message') ?? '';
const output = document.querySelector('#output');

if (output) {
  output.textContent = message;
}

С параметром ?message=%3Cstrong%3EПривет%3C%2Fstrong%3E элемент покажет текст <strong>Привет</strong>. Свойство textContent не превращает значение в HTML-элемент.

Комментарии

Оставьте свой комментарий
Пока никто не оставил комментариев