JavaScript | Как преобразовать строку в URL-объект?

JavaScript | Как преобразовать строку в URL-объект?

Классический сценарий — один параметр — абсолютный путь

У нас есть строка:

let stroka = "https://efim360.ru/blabla123?sort=0#rty"

Эта строка представляет собой полноценный путь до данных. Строка оформлена в виде полного идентификатора ресурса — URI.

Строка начинается со схемы, у строки есть основание, путь , запрос и фрагмент. Полный набор возможных элементов URI.

Из этой строки нам нужно получить объект URL, в котором будут созданы свойства, с готовыми значениями разбора этой строки. Как это сделать?

 

Решение

Мы можем воспользоваться браузерным интерфейсом прикладного программирования, который имеет JavaScript-класс URL.

В этом классе есть конструктор объектов. Конструктор может принимать два параметра. Первый параметр обязателен, второй — нет. Первый параметр — это строка, имитирующая URI.

Давайте создадим новый объект URL.

let objURL = new URL(stroka)
Преобразовали строку в URL объект - JavaScript
Преобразовали строку в URL объект — JavaScript

Теперь мы можем обращаться к этому объекту и получать из него нужные нам значения.

Например, если мы захотим получить схему:

objURL.protocol

'https:'

Если путь, то:

objURL.pathname

'/blabla123'
Получили схему и путь из объекта URL - JavaScript
Получили схему и путь из объекта URL — JavaScript

Можно даже получить поисковые параметры в виде массива из массивов:

[...objURL.searchParams]

[['sort''0']]
Получили параметры URI-запроса из объекта URL - JavaScript
Получили параметры URI-запроса из объекта URL — JavaScript

 

Нестандартный сценарий — два параметра, первый со слешом в начале

А что делать, если у нас есть только часть строки со слешом в начале, которая представляет из себя относительный путь?

Например

let stroka2 = "/dfr400"

Какой объект создастся в таком случае?

let objURL2 = new URL(stroka2)
Ошибка создания объекта URL - JavaScript
Ошибка создания объекта URL — JavaScript

Никакого объекта URL мы не получим, т. к. вызов конструктора вызовет исключение (ошибку).

В этом случае нам нужно иметь ту часть URI-адреса, которая будет хранить в себе схему и основание (протокол и доменное имя). И передавать это всё в конструктор можно во второй параметр. Попробуем передать строку «https://efim360.ru/blabla123»

let objURL2 = new URL(stroka2, "https://efim360.ru/blabla123")
Вызвали конструктор URL с двумя параметрами - JavaScript
Вызвали конструктор URL с двумя параметрами — JavaScript

 

Обратите внимание!!! Мы передали вторым параметром строку, которая содержала свой собственный путь — «blabla123»

Но в итоговом свойстве href у нас содержится адрес, который имеет вид «https://efim360.ru/dfr400»

Синтаксический анализатор распознал косую линию в начале относительного пути у «/dfr400». Он понял, что речь идёт о построении пути сразу после доменного имени (от основания). Из-за этого у второго параметра был полностью отброшен путь «blabla123».

В итоге мы получили нужный нам адрес — «https://efim360.ru/dfr400»

 

Нестандартный сценарий — два параметра, первый без слеша в начале

А что делать, если у нас есть только часть строки без слеша, которая представляет из себя относительный путь?

Например

let stroka3 = "ggggu700"

Какой объект создастся в таком случае?

let objURL3 = new URL(stroka3, "https://efim360.ru/blabla123")
Вызвали конструктор URL с двумя параметрами, первый относительный путь без слеша - JavaScript
Вызвали конструктор URL с двумя параметрами, первый относительный путь без слеша — JavaScript

В этом случае мы получим результат идентичный предыдущему — «https://efim360.ru/ggggu700»

Наш относительный путь добавится сразу после доменного имени.

 

Сценарий с URI-запросом

Например

let stroka4 = "?a=11&b=22&c=33"

Какой объект создастся в таком случае?

let objURL4 = new URL(stroka4, "https://efim360.ru/blabla123")
Создали URL объект из строки URI-запроса и базой - JavaScript
Создали URL объект из строки URI-запроса и базой — JavaScript

В этом случае ситуация меняется. На этот раз синтаксический анализатор понимает, что первым параметром является URI-запрос, а значит речь идёт не об относительном или абсолютном пути. Это значит, что всю строку первого параметра, можно склеить со строкой второго параметра.

В результате мы получим href равный «https://efim360.ru/blabla123?a=11&b=22&c=33»

[...objURL4.searchParams]
Три поисковых параметра в URI-запросе - JavaScript
Три поисковых параметра в URI-запросе — JavaScript

 

Сценарий с URI-фрагментом

Например

let stroka5 = "#tttteeeeqqq"

Какой объект создастся в таком случае?

let objURL5 = new URL(stroka5, "https://efim360.ru/blabla123")
Создали URL объект из строки URI-фрагмента и базой - JavaScript
Создали URL объект из строки URI-фрагмента и базой — JavaScript

Получили результат, аналогичный 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")
Создали URL объект из строки с двумя точками и базой - JavaScript
Создали URL объект из строки с двумя точками и базой — JavaScript

В этом случае конструктор вернул нам значение 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»

Конструктор удалил ровно один сегмент по одной точке.

Создали URL объект из строки с одной точкой и базой - JavaScript
Создали URL объект из строки с одной точкой и базой — JavaScript

 

Три точки

Например три точки:

let stroka8 = ".../zzzz"

В этот раз также вторым параметром передадим «https://efim360.ru/11/22/33/44». Какой объект создастся в таком случае?

let objURL8 = new URL(stroka8, "https://efim360.ru/11/22/33/44")
Создали URL объект из строки с тремя точками и базой - JavaScript
Создали URL объект из строки с тремя точками и базой — JavaScript

Получили — «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")
Создали URL объект из строки с двойными точками и слешами, и базой - JavaScript
Создали URL объект из строки с двойными точками и слешами, и базой — JavaScript

В этом случае мы прыгнули на 3 уровня влево и заменили их на «zzzz»

В итоге href выглядит так — «https://efim360.ru/11/22/33/zzzz»

 

 

 

Информационные ссылки

Стандарт URL — Раздел «URL class» — https://url.spec.whatwg.org/#url-class