Парсинг URL: new URL(), URLSearchParams

Модуль 4: Node.js, Next.js и Angular
4 уровень , 6 лекция
Открыта

1. Класс URL — ваш друг в мире ссылок

Когда сервер получает HTTP-запрос, он видит строку вроде:

/products?category=books&sort=price_asc&page=2

В этой строке зашифровано сразу несколько важных вещей:

  • Путь (/products) — к какому ресурсу обращается клиент.
  • Строка запроса (?category=books&sort=price_asc&page=2) — дополнительные параметры.

Если пытаться разбирать всё это вручную, легко ошибиться (особенно если параметры сложные, их много, или они закодированы). Поэтому современные браузеры и Node.js предоставляют удобные классы для работы с URL.

Создание объекта URL

В современном JavaScript (и в Node.js начиная с 10 версии) есть глобальный класс URL, который превращает строку с адресом в объект с кучей полезных свойств.

Пример:

const url = new URL('https://example.com/products?category=books&sort=price_asc&page=2');
console.log(url.pathname); // /products
console.log(url.search);   // ?category=books&sort=price_asc&page=2
console.log(url.host);     // example.com
console.log(url.protocol); // https:

Что делать, если у вас только путь?

В Node.js, если у вас есть только относительный путь (например, /products?category=books), вы должны указать "базовый" URL:

const url = new URL('/products?category=books', 'https://example.com');

Это похоже на то, как браузер понимает относительные ссылки на странице: он опирается на базовый адрес сайта.

Свойства объекта URL

Вот основные свойства объекта URL:

Свойство Пример значения Описание
href
https://example.com/products?cat=1 Полная строка URL
origin
https://example.com Протокол + домен + порт
protocol
https: Протокол (с двоеточием!)
host
example.com Домен + порт (если есть)
hostname
example.com Только домен
port
443 Только порт (если указан)
pathname
/products Путь (начинается с /)
search
?category=books&sort=price_asc Строка запроса (с вопросительным знаком)
searchParams
URLSearchParams Объект для работы с параметрами
hash
#anchor Якорь (если есть)

Пример:

const url = new URL('https://localhost:3000/users/42?active=true#profile');
console.log(url.pathname);    // /users/42
console.log(url.search);      // ?active=true
console.log(url.hash);        // #profile
console.log(url.port);        // 3000
console.log(url.hostname);    // localhost
console.log(url.origin);      // https://localhost:3000

Парсинг URL в Node.js сервере

Когда вы работаете с сервером на Node.js, в объекте req (request) есть свойство url, но это только строка пути и строки запроса (например, /users?id=42), без домена и протокола.

Чтобы корректно создать объект URL, используйте базовый адрес:

const base = 'http://localhost:3000'; // ваш сервер
const myUrl = new URL(req.url, base);

Пример на сервере:

const http = require('http');

http.createServer((req, res) => {
  const base = `http://${req.headers.host}`;
  const url = new URL(req.url, base);

  console.log('Путь:', url.pathname);
  console.log('Параметры:', url.searchParams);

  res.end('OK');
}).listen(3000);

2. Класс URLSearchParams — магия работы с параметрами

URLSearchParams — это встроенный класс для удобной работы с параметрами строки запроса (то, что после ?).

Получение параметров

const url = new URL('https://example.com/products?category=books&sort=price_asc&page=2');

console.log(url.searchParams.get('category')); // books
console.log(url.searchParams.get('sort'));     // price_asc
console.log(url.searchParams.get('page'));     // 2

Если параметра нет — будет null.

Проверка наличия параметра

console.log(url.searchParams.has('category')); // true
console.log(url.searchParams.has('brand'));    // false

Перебор всех параметров

for (const [key, value] of url.searchParams) {
  console.log(`${key} = ${value}`);
}
// Выведет:
// category = books
// sort = price_asc
// page = 2

Получение нескольких значений

Параметры могут повторяться, например: ?tag=js&tag=node&tag=web

const url = new URL('https://example.com/search?tag=js&tag=node&tag=web');
console.log(url.searchParams.getAll('tag')); // [ 'js', 'node', 'web' ]

Добавление, изменение и удаление параметров

url.searchParams.append('discount', '15');
console.log(url.toString()); // ...&discount=15

url.searchParams.set('page', '3');
console.log(url.toString()); // ...&page=3

url.searchParams.delete('sort');
console.log(url.toString()); // ... без sort

Внимание: после изменений в searchParams строка URL тоже меняется!

3. Применение в нашем сервере: пример мини-приложения

Давайте доработаем наш сервер: пусть он обрабатывает запросы вида /hello?name=Иван и отвечает персональным приветствием.

const http = require('http');

http.createServer((req, res) => {
  const base = `http://${req.headers.host}`;
  const url = new URL(req.url, base);

  // Получаем имя из параметров строки запроса
  const name = url.searchParams.get('name') || 'Гость';

  res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'});
  res.end(`Привет, ${name}!`);
}).listen(3000, () => {
  console.log('Сервер запущен на http://localhost:3000');
});

Проверьте:

4. Пример: обработка фильтров в интернет-магазине

Допустим, у вас сервер принимает запросы вида:

/products?category=books&sort=price_asc&page=2

Как получить все фильтры?

const filters = {};
for (const [key, value] of url.searchParams) {
  filters[key] = value;
}
console.log(filters);
// { category: 'books', sort: 'price_asc', page: '2' }

Можно даже реализовать фильтрацию на сервере (пока "понарошку"):

if (url.pathname === '/products') {
  const category = url.searchParams.get('category');
  const sort = url.searchParams.get('sort');
  // ... фильтрация по данным

  res.writeHead(200, {'Content-Type': 'application/json'});
  res.end(JSON.stringify({ message: `Фильтр: ${category}, сортировка: ${sort}` }));
}

5. Свойства и методы URL и URLSearchParams

Где? Свойство/метод Что делает? Пример
URL
pathname
Путь запроса
/products
URL
search
Строка запроса с ?
?category=books&page=2
URL
searchParams
Объект для работы с параметрами
url.searchParams.get('x')
URLSearchParams
get(name)
Получить значение параметра
get('page')'2'
URLSearchParams
has(name)
Есть ли такой параметр
has('sort')true
URLSearchParams
getAll(name)
Все значения параметра (если их несколько)
getAll('tag')[...]
URLSearchParams
set(name, value)
Задать (или заменить) значение
set('page', '3')
URLSearchParams
append(name, val)
Добавить ещё один параметр
append('tag', 'js')
URLSearchParams
delete(name)
Удалить параметр
delete('sort')
URLSearchParams
[Symbol.iterator]
Перебор всех пар ключ-значение
for (const [k,v] of ...)

6. Типичные ошибки при парсинге URL

Ошибка №1: Не указали базовый адрес при создании URL из относительного пути.
В Node.js new URL('/path', 'http://localhost:3000') — обязательно указывайте второй аргумент, иначе получите ошибку.

Ошибка №2: Использование устаревших способов парсинга.
Раньше в Node.js использовали модуль url.parse(), но сейчас рекомендуется работать с классом URL. Он проще, безопаснее и универсальнее.

Ошибка №3: Игнорирование декодирования параметров.
Если пытаться вручную разбирать строку запроса через split('&'), можно получить странные символы и баги с кодировкой. URLSearchParams всё декодирует автоматически.

Ошибка №4: Не учитывается порт при формировании базового адреса.
Вместо localhost используйте req.headers.host — он уже содержит порт, если не стандартный.

Ошибка №5: Ожидание, что searchParams.get() всегда вернёт строку.
Если параметра нет, будет null. Это может привести к ошибкам при работе с числовыми значениями (parseInt(null) даст NaN).

1
Задача
Модуль 4: Node.js, Next.js и Angular, 4 уровень, 6 лекция
Недоступна
Извлечение пути и строки запроса из URL
Извлечение пути и строки запроса из URL
1
Задача
Модуль 4: Node.js, Next.js и Angular, 4 уровень, 6 лекция
Недоступна
Получение параметров строки запроса
Получение параметров строки запроса
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ