JavaScript | Как преобразовать относительные URL-пути с точками в абсолютные на основе HTML-атрибута href и адреса нахождения?

JavaScript | Как преобразовать относительные URL-пути с точками в абсолютные на основе HTML-атрибута href и адреса нахождения?

Дано

Есть строка:

'../aa/bb.html'

Нужно получить:

'https://example.com/xyz/aa/bb.html'

 

Строку с относительным путём мы получили из HTML-разметки документа, когда получали данные при помощи выборки Fetch.

Адрес выборки:

'https://example.com/xyz/111/222.html'

 

Как преобразовать относительный путь с точками в абсолютный?

 

Способ № 1 — Использование конструктора URL

Когда мы работаем в браузере, то у нас в распоряжении имеется специальный интерфейс прикладного программирования (API), который называется URL. Это довольно большой стандарт, который позволяет работать с URL-адресами, схемами, портами, основаниями, путями, запросами, фрагментами и т.д.. В общем интерфейс полностью охватывает теоретическую часть унифицированных идентификаторов ресурсов RFC 3986.

В основном функционале URL API работает базовый синтаксический анализатор URL-адресов (basic URL parser). У него очень длинный алгоритм. Кому интересно — можете ознакомиться. Это я к тому, что больше не нужно придумывать свои собственные коды обработки строк и писать свои анализаторы. Всё уже давно придумано. Просто нужно разобраться как это работает.

С чего начать? Я бы начал с того, что стандарт URL API определяет класс URL (URL class) для работы на JavaScript.

URL class для создания JavaScript-объектов URL-адресов из строк
URL class для создания JavaScript-объектов URL-адресов из строк

 

В этом классе определён конструктор, который умеет создавать объекты URL-адресов на основе строк JavaScript.

Идея простая. Мы передаём в конструктор строку, а конструктор возвращает нам объект со свойствами, который подходят под стандарт URI.

 

ВАЖНО!!!

Конструктор URL, может принимать два параметра. Один обязательный, второй опциональный. Для задачи преобразования относительных путей в абсолютные НУЖНО ВЫЗЫВАТЬ КОНСТРУКТОР с ДВУМЯ ПАРАМЕТРАМИ.

Первый параметр — это то, из чего мы хотим сделать URL-объект.

Второй параметр — это то, откуда мы вытащили то, что хотим сделать URL-объектом.

 

../aa/bb.html‘ — из этого мы хотим сделать URL-объект, чтобы потом вытащить абсолютный путь из свойства.

https://example.com/xyz/111/222.html‘ — отсюда мы получили разметку, в которой нашли относительный путь.

 

Решение:

let absolute_path = new URL( '../aa/bb.html' , 'https://example.com/xyz/111/222.html' )

Вызов этой команды создаёт новый объект — экземпляр класса URL.

Создали объект URL-адреса из относительного пути, конструктором new URL() - JavaScript
Создали объект URL-адреса из относительного пути, конструктором new URL() — JavaScript

Мы создавали URL-объект из относительной ссылки (из строки JS) специально для того, чтобы сгенерировать абсолютный путь, который можно достать из объекта absolute_path, путём обращения к его свойству href.

absolute_path.href
Получили абсолютный путь из свойства href URL-объекта JavaScript
Получили абсолютный путь из свойства href URL-объекта JavaScript

Нам вернулась строка:

'https://example.com/xyz/aa/bb.html'

Это именно то, что мы и хотели получить. В нашем случае двоеточие из относительного пути было правильно преобразовано. Двоеточие удалило в базовом адресе лишние участки, которые разделены косой линией.

 

Термины и понятия

path-relative-URL string

Строка URL-адреса относительно пути должна состоять из нуля или более строк сегмента URL-пути, разделенных друг от друга символом U+002F (/), и не начинаться с U+002F (/).

single-dot path segment

Сегмент пути с одной точкой должен быть «.« или должен соответствовать ASCII без учета регистра для «%2e«.

double-dot path segment

Сегмент пути с двумя точками должен быть «..« или должен соответствовать ASCII без учета регистра для «.%2e«, «%2e.» или «%2e%2e«.

Из RFC 3986

Путь сегментов «.» и «..«, также известный как «точечные сегменты» (dot-segments), определены для относительной ссылки в иерархии имён путей. Они предназначены для использования в начале ссылки на относительный путь (раздел 4.2) для указания относительного положения в иерархическом дереве имен. Это похоже на их роль в структурах файловых каталогов некоторых операционных систем для указания текущего каталога и родительского каталога соответственно. Однако, в отличие от файловой системы, эти точечные сегменты интерпретируются только в иерархии путей URI и удаляются как часть процесса разрешения (раздел 5.2).

 

Памятка

/ — указывает относительный путь от корня (от домена). Базовый URL (текущий адрес) тут не важен.
./ — указывает относительный путь от последнего/текущего узла (от самого крайнего правого слеша). Базовый URL (текущий адрес) обязателен.
../ — указывает относительный путь от предпоследнего узла (от второго слеша справа). Базовый URL (текущий адрес) обязателен.
# — добавляет фрагмент к Базовому URL (текущему адресу). Нужен для навигации по элементам документа.
? — добавляет запрос к Базовому URL (текущему адресу). Нужен для передачи параметров из документа на сервер.

 

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

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

Стандарт URLhttps://url.spec.whatwg.org