URL и строка запроса в Node.js: разбор и сборка
Содержание
О проверке кода. Примеры не запускались в этой сессии (по договорённости — фокус на контенте, а не прогонах). Говорим прямо, а не ставим бейдж «проверено».
Работа с URL — постоянная задача в Node.js: разобрать входящий адрес, собрать ссылку к API, прочитать параметры запроса. Современный Node решает это стандартными инструментами, теми же, что в браузере.
Разбор URL
const url = new URL('https://example.ru:8080/blog/post?id=42&tag=node#top');
url.protocol; // 'https:'
url.hostname; // 'example.ru'
url.port; // '8080'
url.pathname; // '/blog/post'
url.search; // '?id=42&tag=node'
url.hash; // '#top'
url.searchParams; // объект URLSearchParams
Класс URL разбирает адрес на составные части — тот же URL, что в браузере, встроен в Node без импорта. Он заменил устаревший url.parse(). Каждая часть доступна как свойство. Невалидная строка бросит ошибку, поэтому разбор внешних URL стоит обернуть в try/catch.
- 1 protocol + hostnamehttps:// example.ru — куда идём
- 2 pathname/blog/post — путь к ресурсу
- 3 search (query)?id=42&tag=node — параметры
- 4 hash#top — якорь, на сервер не шлётся
Query-параметры через searchParams
const url = new URL('https://example.ru/search?q=node&page=2&tag=js&tag=web');
url.searchParams.get('q'); // 'node'
url.searchParams.get('page'); // '2' (всегда строка!)
url.searchParams.getAll('tag'); // ['js', 'web'] — все значения одного имени
url.searchParams.has('q'); // true
// перебор всех параметров
for (const [key, value] of url.searchParams) {
console.log(key, value);
}
url.searchParams — объект URLSearchParams с удобными методами. get возвращает первое значение (всегда строка — число парсите сами), getAll — все значения для повторяющегося имени (?tag=js&tag=web). Он итерируемый, поэтому перебирается в for...of. Ручной разбор строки после ? больше не нужен.
Изменение и сборка
const url = new URL('https://api.example.ru/users');
url.searchParams.set('page', '2'); // добавить/заменить
url.searchParams.append('role', 'admin'); // добавить ещё значение
url.searchParams.set('q', 'привет мир'); // пробелы и кириллица — закодируются сами
url.href;
// 'https://api.example.ru/users?page=2&role=admin&q=%D0%BF%D1%80%D0%B8...'
url.toString(); // то же самое
Сборка URL с параметрами — через set/append, потом url.href. Ключевое удобство: значения кодируются автоматически. Пробелы, кириллица, &, = внутри значения экранируются сами — не нужно вручную звать encodeURIComponent и рисковать сломанной ссылкой. Это главная причина не склеивать URL строками.
Почему не строками и не querystring
// ❌ ручная склейка — ломается на спецсимволах
const bad = `https://api.ru/search?q=${query}`; // если query = 'a&b=c' — всё сломается
// ❌ устаревший модуль querystring
const querystring = require('node:querystring');
querystring.stringify({ q: query }); // работает, но заменён
// ✅ URLSearchParams — стандарт, кодирует сам
const params = new URLSearchParams({ q: query, page: '2' });
const good = `https://api.ru/search?${params}`;
Ручная склейка ?q=${value} — источник багов: любой спецсимвол в значении (&, =, пробел, кириллица) ломает URL или, хуже, создаёт уязвимость. Модуль querystring устарел — его заменил URLSearchParams, который работает одинаково в браузере и Node, корректно кодирует и удобнее. В новом коде берут только его.
URLSearchParams можно создать из объекта — удобно собирать параметры из обычного объекта:
const params = new URLSearchParams({ q: 'node', page: '2' });
params.toString(); // 'q=node&page=2'
Относительные URL и базовый адрес
// разрешить относительный путь относительно базового
const base = 'https://example.ru/blog/';
new URL('post-1', base).href; // 'https://example.ru/blog/post-1'
new URL('/about', base).href; // 'https://example.ru/about' (от корня)
new URL('../news', base).href; // 'https://example.ru/news'
Второй аргумент URL — базовый адрес, относительно которого разрешается путь. Это избавляет от ручной склейки путей с учётом /, .. и слэшей — частая задача при работе со ссылками и HTTP-клиентами.
Смежные темы: обработка ошибок — разбор внешних URL; HTTP-клиент fetch — куда идут собранные URL; создание HTTP-сервера. Полный список — в уроках Node.js.