Классический сценарий — один параметр — абсолютный путь
У нас есть строка:
let stroka = "https://efim360.ru/blabla123?sort=0#rty"
Эта строка представляет собой полноценный путь до данных. Строка оформлена в виде полного идентификатора ресурса — URI.
Строка начинается со схемы, у строки есть основание, путь , запрос и фрагмент. Полный набор возможных элементов URI.
Из этой строки нам нужно получить объект URL, в котором будут созданы свойства, с готовыми значениями разбора этой строки. Как это сделать?
Решение
Мы можем воспользоваться браузерным интерфейсом прикладного программирования, который имеет JavaScript-класс URL.
В этом классе есть конструктор объектов. Конструктор может принимать два параметра. Первый параметр обязателен, второй — нет. Первый параметр — это строка, имитирующая URI.
Давайте создадим новый объект URL.
let objURL = new URL(stroka)
Теперь мы можем обращаться к этому объекту и получать из него нужные нам значения.
Например, если мы захотим получить схему:
objURL.protocol 'https:'
Если путь, то:
objURL.pathname '/blabla123'
Можно даже получить поисковые параметры в виде массива из массивов:
[...objURL.searchParams] [['sort', '0']]
Нестандартный сценарий — два параметра, первый со слешом в начале
А что делать, если у нас есть только часть строки со слешом в начале, которая представляет из себя относительный путь?
Например
let stroka2 = "/dfr400"
Какой объект создастся в таком случае?
let objURL2 = new URL(stroka2)
Никакого объекта URL мы не получим, т. к. вызов конструктора вызовет исключение (ошибку).
В этом случае нам нужно иметь ту часть URI-адреса, которая будет хранить в себе схему и основание (протокол и доменное имя). И передавать это всё в конструктор можно во второй параметр. Попробуем передать строку «https://efim360.ru/blabla123»
let objURL2 = new URL(stroka2, "https://efim360.ru/blabla123")
Обратите внимание!!! Мы передали вторым параметром строку, которая содержала свой собственный путь — «blabla123»
Но в итоговом свойстве href у нас содержится адрес, который имеет вид «https://efim360.ru/dfr400»
Синтаксический анализатор распознал косую линию в начале относительного пути у «/dfr400». Он понял, что речь идёт о построении пути сразу после доменного имени (от основания). Из-за этого у второго параметра был полностью отброшен путь «blabla123».
В итоге мы получили нужный нам адрес — «https://efim360.ru/dfr400»
Нестандартный сценарий — два параметра, первый без слеша в начале
А что делать, если у нас есть только часть строки без слеша, которая представляет из себя относительный путь?
Например
let stroka3 = "ggggu700"
Какой объект создастся в таком случае?
let objURL3 = new URL(stroka3, "https://efim360.ru/blabla123")
В этом случае мы получим результат идентичный предыдущему — «https://efim360.ru/ggggu700»
Наш относительный путь добавится сразу после доменного имени.
Сценарий с URI-запросом
Например
let stroka4 = "?a=11&b=22&c=33"
Какой объект создастся в таком случае?
let objURL4 = new URL(stroka4, "https://efim360.ru/blabla123")
В этом случае ситуация меняется. На этот раз синтаксический анализатор понимает, что первым параметром является URI-запрос, а значит речь идёт не об относительном или абсолютном пути. Это значит, что всю строку первого параметра, можно склеить со строкой второго параметра.
В результате мы получим href равный «https://efim360.ru/blabla123?a=11&b=22&c=33»
[...objURL4.searchParams]
Сценарий с URI-фрагментом
Например
let stroka5 = "#tttteeeeqqq"
Какой объект создастся в таком случае?
let objURL5 = new URL(stroka5, "https://efim360.ru/blabla123")
Получили результат, аналогичный URI-запросу. Строки тупо склеились — «https://efim360.ru/blabla123#tttteeeeqqq»
Сценарий с точками
Две точки
И вот тут ситуация меняется. точки представляют из себя сложные преобразования.
Например всего две точки:
let stroka6 = "../ww"
В этот раз вторым параметром передадим «https://efim360.ru/11/22/33/44». Какой объект создастся в таком случае?
let objURL6 = new URL(stroka6, "https://efim360.ru/11/22/33/44")
В этом случае конструктор вернул нам значение href в виде «https://efim360.ru/11/22/ww»
Две точки сработали как два сегмента в пути и удалили часть «/33/44″
Одна точка
Например всего одна точка:
let stroka7 = "./kk"
В этот раз также вторым параметром передадим «https://efim360.ru/11/22/33/44». Какой объект создастся в таком случае?
let objURL7 = new URL(stroka7, "https://efim360.ru/11/22/33/44")
Получим href — «https://efim360.ru/11/22/33/kk»
Конструктор удалил ровно один сегмент по одной точке.
Три точки
Например три точки:
let stroka8 = ".../zzzz"
В этот раз также вторым параметром передадим «https://efim360.ru/11/22/33/44». Какой объект создастся в таком случае?
let objURL8 = new URL(stroka8, "https://efim360.ru/11/22/33/44")
Получили — «https://efim360.ru/11/22/33/…/zzzz»
В этом случае точки были особым образом распознаны синтаксическим анализатором т. к. их количество более двух. 44 исчезло, а вместо него прописалась наша вставка.
По стандарту HTML относительные пути, конвертирующие уровни адреса, могут иметь одну или две точки. Этот пример самый непонятный из всех. Как он работает нужно разбираться под капотом детально.
Итог
Одна точка — очищаем последнюю часть пути. Всё что после последнего слеша
Две точки — очищаем две последние части пути. Прыгаем на предыдущую часть, удаляем её и всё что до конца.
Сценарий с двойными точками и слешами
Ну и напоследок маразм с глубиной относительных путей через двойные точки и слеши
Например три точки:
let stroka9 = "../../zzzz"
В этот раз вторым параметром передадим «https://efim360.ru/11/22/33/44/55/66». Какой объект создастся в таком случае?
let objURL9 = new URL(stroka9, "https://efim360.ru/11/22/33/44/55/66")
В этом случае мы прыгнули на 3 уровня влево и заменили их на «zzzz»
В итоге href выглядит так — «https://efim360.ru/11/22/33/zzzz»
Информационные ссылки
Стандарт URL — Раздел «URL class» — https://url.spec.whatwg.org/#url-class