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:
| Свойство | Пример значения | Описание |
|---|---|---|
|
https://example.com/products?cat=1 | Полная строка URL |
|
https://example.com | Протокол + домен + порт |
|
https: | Протокол (с двоеточием!) |
|
example.com | Домен + порт (если есть) |
|
example.com | Только домен |
|
443 | Только порт (если указан) |
|
/products | Путь (начинается с /) |
|
?category=books&sort=price_asc | Строка запроса (с вопросительным знаком) |
|
URLSearchParams | Объект для работы с параметрами |
|
#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');
});
Проверьте:
- http://localhost:3000/hello?name=Катя → "Привет, Катя!"
- http://localhost:3000/hello → "Привет, Гость!"
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 | |
Путь запроса | |
| URL | |
Строка запроса с ? | |
| URL | |
Объект для работы с параметрами | |
| URLSearchParams | |
Получить значение параметра | |
| URLSearchParams | |
Есть ли такой параметр | |
| URLSearchParams | |
Все значения параметра (если их несколько) | |
| URLSearchParams | |
Задать (или заменить) значение | |
| URLSearchParams | |
Добавить ещё один параметр | |
| URLSearchParams | |
Удалить параметр | |
| URLSearchParams | |
Перебор всех пар ключ-значение | |
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).
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ