Параметры URL в JavaScript: от простого к сложному
Каждый разработчик хотя бы раз сталкивался с задачей: нужно вытащить данные из адресной строки браузера. Вы открываете страницу, видите что-то вроде /products?id=42&category=books — и понимаете: где-то внутри этого набора символов спрятаны важные данные. Как их достать? Вопрос, который собрал тысячи голосов на Stack Overflow, звучит так: "How can I get query string values in JavaScript?". Сегодня мы не просто дадим готовый ответ — мы заглянем под капот этого процесса и разберём, как работает парсинг URL в JavaScript на всех уровнях.
Почему это важно? Потому что параметры URL — это основа современного веба. Передача данных между страницами, фильтрация товаров, аналитика, реферальные ссылки — всё это строится на простых строках после знака вопроса. И если вы пишете на JavaScript, умение работать с query string — не опция, а обязательный навык.
Что такое query string и как её увидеть в браузере
Для начала давайте разберёмся с терминами. Query string (строка запроса) — это часть URL, которая начинается после вопросительного знака. Например, в адресе:
https://example.com/search?q=javascript&lang=ru&page=1
всё, что идёт после ? — это query string. Она состоит из пар ключ=значение, разделённых амперсандом (&). Каждый ключ может встречаться несколько раз — и это важно помнить.
Чтобы получить эту строку в JavaScript, достаточно обратиться к свойству:
const queryString = window.location.search;
console.log(queryString); // "?q=javascript&lang=ru&page=1"
Обратите внимание: свойство возвращает строку вместе с вопросительным знаком. Это отправная точка для всех дальнейших манипуляций.
Способ №1: URLSearchParams — современный и простой
Если вы пишете код для современных браузеров (а это 99% случаев), используйте встроенный API URLSearchParams. Он появился в 2016 году и с тех пор стал стандартом де-факто для работы с параметрами URL. Давайте посмотрим, как это работает:
// Получаем строку запроса
const queryString = window.location.search;
// Создаём объект URLSearchParams
const params = new URLSearchParams(queryString);
// Получаем значение по ключу
const q = params.get('q'); // "javascript"
const lang = params.get('lang'); // "ru"
const page = params.get('page'); // "1"
// Проверяем, есть ли параметр
console.log(params.has('lang')); // true
// Получаем все значения, если ключ повторяется
params.append('q', 'python');
console.log(params.getAll('q')); // ["javascript", "python"]
// Перебираем все параметры
for (const [key, value] of params) {
console.log(`${key}: ${value}`);
}
// Вывод:
// q: javascript
// lang: ru
// page: 1
// q: python
Под капотом URLSearchParams автоматически декодирует закодированные символы (например, %20 превращает в пробел) и корректно обрабатывает сложные случаи вроде повторяющихся ключей. Это не просто удобно — это безопасно.
Как это работает под капотом?
Когда вы создаёте new URLSearchParams(queryString), движок JavaScript выполняет следующие шаги:
- Удаляет ведущий вопросительный знак (если он есть).
- Разбивает строку по символу
&, получая массив пар. - Каждую пару разбивает по первому символу
=на ключ и значение. - Декодирует URI-компоненты — заменяет
%20на пробел,%23на#и так далее. - Сохраняет всё в структуру, где каждому ключу соответствует массив значений (даже если он один).
Этот процесс полностью обратим. Вы можете модифицировать параметры и получить строку обратно:
const params = new URLSearchParams('name=Иван&age=30');
params.set('age', '31');
params.append('city', 'Москва');
console.log(params.toString()); // "name=%D0%98%D0%B2%D0%B0%D0%BD&age=31&city=%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0"
Обратите внимание: кириллица автоматически кодируется. Это важно, потому что URL может содержать только ASCII-символы.
Способ №2: Ручной парсинг — когда нужно больше контроля
Иногда встроенного API недостаточно. Например, вы работаете в среде, где URLSearchParams не поддерживается (редкий случай) или вам нужна кастомная логика обработки. Тогда вы можете написать парсер вручную. Давайте разберём, как это сделать правильно:
function parseQueryString(queryString) {
// Убираем вопросительный знак в начале
const cleanString = queryString.startsWith('?') ? queryString.slice(1) : queryString;
// Если строка пуста, возвращаем пустой объект
if (!cleanString) return {};
// Разбиваем по амперсанду
const pairs = cleanString.split('&');
// Собираем результат
const result = {};
for (const pair of pairs) {
// Разбиваем по первому знаку равенства
const separatorIndex = pair.indexOf('=');
let key, value;
if (separatorIndex === -1) {
// Если знака равенства нет, ключ есть, значение — пустая строка
key = decodeURIComponent(pair);
value = '';
} else {
key = decodeURIComponent(pair.slice(0, separatorIndex));
value = decodeURIComponent(pair.slice(separatorIndex + 1));
}
// Обрабатываем повторяющиеся ключи
if (key in result) {
if (Array.isArray(result[key])) {
result[key].push(value);
} else {
result[key] = [result[key], value];
}
} else {
result[key] = value;
}
}
return result;
}
// Использование
const params = parseQueryString('?q=javascript&lang=ru&q=python');
console.log(params.q); // ["javascript", "python"]
console.log(params.lang); // "ru"
Что здесь происходит под капотом? Мы вручную выполняем те же шаги, что и URLSearchParams: удаляем ?, разбиваем по &, затем по =, декодируем символы и собираем результат. Разница лишь в том, что мы контролируем каждый шаг. Например, можем решить, что делать с повторяющимися ключами — собирать их в массив или оставлять только последнее значение.
Способ №3: Использование URL API — для полного разбора URL
Если вам нужно не только получить параметры, но и разобрать URL целиком, используйте конструктор URL. Он возвращает объект со всеми компонентами адреса:
const url = new URL('https://example.com/search?q=javascript&lang=ru#section1');
console.log(url.search); // "?q=javascript&lang=ru"
console.log(url.searchParams); // URLSearchParams { 'q' => 'javascript', 'lang' => 'ru' }
console.log(url.hash