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.

Из чего состоит URL
  1. 1 protocol + hostnamehttps:// example.ru — куда идём
  2. 2 pathname/blog/post — путь к ресурсу
  3. 3 search (query)?id=42&tag=node — параметры
  4. 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.

Частые вопросы

Как разобрать URL в Node.js?
Через встроенный класс URL: new URL(строка) даёт объект со свойствами protocol, hostname, pathname, searchParams. Это стандартный способ, тот же, что в браузере, заменивший устаревший модуль url.parse.
Как работать с параметрами запроса?
Через url.searchParams — объект URLSearchParams с методами get, getAll, set, append, delete. Он сам декодирует значения и позволяет удобно читать и менять query-часть без ручного разбора строки после знака вопроса.
Почему модуль querystring устарел?
Его заменил стандартный URLSearchParams, который работает одинаково в браузере и Node, корректно кодирует значения и удобнее в использовании. querystring оставлен для совместимости, но в новом коде берут URLSearchParams.
Как правильно закодировать значение в URL?
URLSearchParams кодирует автоматически при set и append, поэтому пробелы, кириллица и спецсимволы становятся безопасными сами. Для отдельного значения вручную есть encodeURIComponent, но при сборке через URLSearchParams он не нужен.
Как собрать URL с параметрами?
Создать объект URL, добавить параметры через url.searchParams.set или append, затем взять url.href или url.toString. Значения закодируются автоматически, и получится корректная строка без ручной склейки.