URL - это встроенный объект для работы с адресами.
Он помогает не склеивать URL вручную строками, а разбирать и собирать адрес через понятные свойства: protocol, hostname, pathname, search, hash и другие.
Чаще всего URL используют, когда нужно:
- разобрать адрес на отдельные части
- добавить или изменить параметры запроса
- собрать URL из базового адреса и относительного пути
- безопасно подготовить адрес для перехода или запроса
- проверить, что строка действительно является корректным URL
Синтаксис
Объект создают через new URL().
new URL(url, base)
Где:
url- абсолютный или относительный адресbase- необязательный базовый адрес, нужен для относительных URL
Пример с абсолютным адресом:
const url = new URL("https://learn-javascript.ru/catalog?sort=price");
Пример с относительным адресом:
const url = new URL("/catalog", "https://learn-javascript.ru");
Без new использовать URL нельзя.
URL("https://learn-javascript.ru"); // TypeError
Что возвращает URL
new URL() возвращает объект URL.
const url = new URL("https://learn-javascript.ru/catalog");
console.log(url instanceof URL); // true
console.log(url.href); // "https://learn-javascript.ru/catalog"
Сам объект хранит адрес и даёт удобный доступ к его частям.
Если нужно снова получить обычную строку, можно использовать href или toString().
const url = new URL("https://learn-javascript.ru/catalog");
console.log(url.href); // "https://learn-javascript.ru/catalog"
console.log(url.toString()); // "https://learn-javascript.ru/catalog"
Из каких частей состоит URL
Возьмём такой адрес:
const url = new URL("https://learn-javascript.ru:8080/catalog/books?sort=price#reviews");
Теперь его можно разобрать на части:
console.log(url.protocol); // "https:"
console.log(url.host); // "learn-javascript.ru:8080"
console.log(url.hostname); // "learn-javascript.ru"
console.log(url.port); // "8080"
console.log(url.pathname); // "/catalog/books"
console.log(url.search); // "?sort=price"
console.log(url.hash); // "#reviews"
Полный адрес лежит в href.
console.log(url.href);
// "https://learn-javascript.ru:8080/catalog/books?sort=price#reviews"
Свойство origin содержит протокол, домен и порт.
console.log(url.origin); // "https://learn-javascript.ru:8080"
host и hostname - не одно и то же
Эти свойства легко перепутать.
const url = new URL("https://learn-javascript.ru:8080/catalog");
console.log(url.host); // "learn-javascript.ru:8080"
console.log(url.hostname); // "learn-javascript.ru"
host содержит домен вместе с портом, если порт указан.
hostname содержит только имя хоста без порта.
URL можно изменять через свойства
Свойства объекта URL можно менять, и полный адрес пересоберётся автоматически.
const url = new URL("https://learn-javascript.ru/catalog");
url.pathname = "/products";
url.search = "?page=2";
url.hash = "#top";
console.log(url.href);
// "https://learn-javascript.ru/products?page=2#top"
Это удобнее, чем вручную следить за слешами, вопросительными знаками и решётками.
Можно менять и домен:
const url = new URL("https://learn-javascript.ru/catalog");
url.hostname = "shop.learn-javascript.ru";
console.log(url.href);
// "https://shop.learn-javascript.ru/catalog"
Относительный URL и базовый адрес
Если адрес относительный, нужно передать второй аргумент base.
const url = new URL("/catalog", "https://learn-javascript.ru");
console.log(url.href); // "https://learn-javascript.ru/catalog"
Без базового адреса относительная строка не будет понятна.
new URL("/catalog"); // TypeError
В браузере в качестве базы часто используют текущий адрес страницы.
const url = new URL("/catalog", window.location.origin);
Если путь не начинается со слеша, он считается относительным к текущему пути базы.
const url = new URL("books", "https://learn-javascript.ru/catalog/");
console.log(url.href); // "https://learn-javascript.ru/catalog/books"
А путь со слешем начинается от корня сайта.
const url = new URL("/books", "https://learn-javascript.ru/catalog/");
console.log(url.href); // "https://learn-javascript.ru/books"
Параметры запроса через searchParams
Самая практичная часть URL - свойство searchParams.
Оно позволяет работать с параметрами после ? не через ручную склейку строк, а через методы.
const url = new URL("https://learn-javascript.ru/search");
url.searchParams.set("q", "javascript");
url.searchParams.set("page", "1");
console.log(url.href);
// "https://learn-javascript.ru/search?q=javascript&page=1"
Получить значение параметра можно через get().
const url = new URL("https://learn-javascript.ru/search?q=javascript&page=1");
console.log(url.searchParams.get("q")); // "javascript"
console.log(url.searchParams.get("page")); // "1"
Проверить наличие параметра можно через has().
const url = new URL("https://learn-javascript.ru/search?q=javascript");
console.log(url.searchParams.has("q")); // true
console.log(url.searchParams.has("page")); // false
Удалить параметр можно через delete().
const url = new URL("https://learn-javascript.ru/search?q=javascript&page=1");
url.searchParams.delete("page");
console.log(url.href);
// "https://learn-javascript.ru/search?q=javascript"
set() и append()
Для параметров важно различать set() и append().
set() устанавливает одно значение и заменяет старое.
const url = new URL("https://learn-javascript.ru/search?q=js");
url.searchParams.set("q", "javascript");
console.log(url.href);
// "https://learn-javascript.ru/search?q=javascript"
append() добавляет ещё одно значение с тем же именем.
const url = new URL("https://learn-javascript.ru/catalog");
url.searchParams.append("tag", "js");
url.searchParams.append("tag", "frontend");
console.log(url.href);
// "https://learn-javascript.ru/catalog?tag=js&tag=frontend"
Это полезно, если сервер ожидает несколько одинаковых параметров.
URL сам кодирует параметры
Если в параметре есть пробелы, русские буквы или специальные символы, searchParams подготовит их для URL.
const url = new URL("https://learn-javascript.ru/search");
url.searchParams.set("q", "уроки javascript");
console.log(url.href);
В строке адреса значение будет закодировано так, чтобы его можно было безопасно передать в URL.
Это одна из причин не собирать параметры вручную:
// Лучше не так
const badUrl = "/search?q=уроки javascript";
Правильнее:
const url = new URL("/search", "https://learn-javascript.ru");
url.searchParams.set("q", "уроки javascript");
hash - часть адреса после
hash хранит фрагмент адреса.
const url = new URL("https://learn-javascript.ru/docs#install");
console.log(url.hash); // "#install"
Фрагмент часто используют для перехода к конкретному блоку страницы.
const url = new URL("https://learn-javascript.ru/docs");
url.hash = "examples";
console.log(url.href);
// "https://learn-javascript.ru/docs#examples"
Можно указывать значение с # или без него. В итоговом адресе решётка будет стоять правильно.
Проверка URL через try…catch
Если строка не похожа на корректный абсолютный URL, new URL() выбросит ошибку.
try {
const url = new URL("not a url");
console.log(url.href);
} catch (error) {
console.log("Некорректный URL");
}
Для относительного адреса можно передать базу:
try {
const url = new URL("/catalog", "https://learn-javascript.ru");
console.log(url.href);
} catch (error) {
console.log("Некорректный URL");
}
Так можно аккуратно проверять адреса, которые пришли от пользователя или из внешних данных.
URL не отправляет запрос
URL только создаёт и разбирает адрес.
Сам по себе объект URL ничего не загружает и не отправляет.
const url = new URL("https://learn-javascript.ru/api/users");
console.log(url.href);
Если нужно сделать сетевой запрос, адрес можно передать в fetch().
const url = new URL("/api/users", window.location.origin);
fetch(url);
Здесь URL отвечает за адрес, а fetch() - за сам запрос.
Когда это полезно
URL особенно удобен, когда адрес нужно не просто хранить строкой, а менять или анализировать.
Например, собрать ссылку на страницу каталога:
function createCatalogUrl(category, page) {
const url = new URL("/catalog", "https://learn-javascript.ru");
url.searchParams.set("category", category);
url.searchParams.set("page", String(page));
return url.href;
}
console.log(createCatalogUrl("books", 2));
// "https://learn-javascript.ru/catalog?category=books&page=2"
Или получить параметры из текущего адреса страницы:
const currentUrl = new URL(window.location.href);
const page = currentUrl.searchParams.get("page") || "1";
const category = currentUrl.searchParams.get("category") || "all";
console.log(page, category);
Частые ошибки
Вызывать URL без new
const url = URL("https://learn-javascript.ru"); // TypeError
Нужно создавать объект через new URL().
const url = new URL("https://learn-javascript.ru");
Создавать относительный URL без base
const url = new URL("/catalog"); // TypeError
Для относительного адреса нужен базовый адрес.
const url = new URL("/catalog", "https://learn-javascript.ru");
Путать host и hostname
const url = new URL("https://learn-javascript.ru:8080/catalog");
console.log(url.host); // "learn-javascript.ru:8080"
console.log(url.hostname); // "learn-javascript.ru"
Если нужен домен без порта, используйте hostname.
Вручную склеивать параметры
const query = "уроки javascript";
const url = "/search?q=" + query;
Так легко забыть про кодирование специальных символов.
Лучше использовать searchParams.
const url = new URL("/search", "https://learn-javascript.ru");
url.searchParams.set("q", "уроки javascript");
Забывать, что search и hash включают специальные символы
const url = new URL("https://learn-javascript.ru/catalog?page=1#top");
console.log(url.search); // "?page=1"
console.log(url.hash); // "#top"
Если нужен параметр без ?, берите его через searchParams.
console.log(url.searchParams.get("page")); // "1"
Быстрая памятка
URLсоздают черезnew URL()- абсолютный URL можно создать без второго аргумента
- относительный URL требует базовый адрес
base hrefхранит полный адрес строкойoriginхранит протокол, домен и портhostвключает порт,hostnameне включает портpathnameхранит путьsearchхранит строку параметров вместе с?hashхранит фрагмент вместе с#- параметры удобнее менять через
searchParams searchParams.set()заменяет значениеsearchParams.append()добавляет ещё одно значениеURLпомогает собрать адрес, но сам не отправляет запрос
Коротко
URL в JavaScript нужен для безопасной и удобной работы с адресами. Он разбирает строку URL на части, позволяет менять путь, домен, параметры и фрагмент, автоматически пересобирает итоговый адрес и помогает избежать ручной склейки строк там, где легко ошибиться со слешами, ?, & или кодированием символов.