Легко анализируйте URL-адреса в JavaScript с помощью parse-url
Анализ URL-адресов - это обычная задача, которую нужно выполнять во время веб-разработки, и она кажется простой, но может стать сложной. Нечасто можно встретить модуль, который делает синтаксический анализ настолько простым, что вам не нужно много думать.
Несмотря на то, что он относительно молод (опубликован в июне 2021 года), с почти 3 миллионами загрузок в неделю, parse-url является одним из лучших модулей для синтаксического анализа URL-адресов в JavaScript.
В этой статье мы рассмотрим все его возможности и то, как он облегчает нашу жизнь.
Части URL
URL-адрес состоит из многих частей, поэтому разбиение его на части без простого синтаксического анализа строк - мощный инструмент. Каждый URL-адрес имеет одни и те же основные части, а другие части являются необязательными в зависимости от запроса или действия.
Составные элементы URL-адреса:
- Scheme - используется для идентификации протокола, используемого для получения ресурса в Интернете.Некоторые из наиболее популярных протоколов: HTTP, HTTPS, IP, ICMP, TCP, UDP и т.д.
- Host - имя хоста, у которого есть ресурс, который мы получаем (
www.somehost.com
) - Path - путь к ресурсу, находящемуся на хосте (
www.somehost.com/path/to/index.html
) - Query - строка, содержащая пары ключ-значение (
www.somehost.com/index?key=value&key2=value2
)
Это основные фрагменты URL-адреса, но мы увидим, что мы можем получить еще больше с помощью parse-url в очень удобочитаемом и снова анализируемом формате.
Установка и настройка модуля parse-url
Начнем с создания папки для нашего мини-проекта под названием parse_url
. В папку мы можем установить модуль, используя npm
:
npm i parse-url
Чтобы использовать модуль в нашем коде (в файле index.js ), мы должны обратиться к нему с помощью require
:
const parseUrl = require('parse-url');
Вот и все! Посмотрим, что предлагает этот модуль.
Разбор URL
Для начала, давайте рассмотрим простой URL: https://www.stackabuse.com
. Конструктор parseUrl
принимает два параметра string_url
и необязательный normalize
.
По умолчанию он установлен как false
, и предполагается, что предоставляемые URL-адреса уже нормализованы. Когда true
он преобразует ненормализованный URL-адрес в нормализованный. Например:
someRandomUrl.com:80 --> http://someRandomUrl.com
Это называется нормализацией URL. Модуль parse-url
основывает нормализацию на модуле normalize-url
и работает точно так же, как показано выше.
Давайте проанализируем URL:
const url = 'https://www.stackabuse.com/';
const parsedUrl = parseUrl(url);
console.log(parsedUrl)
Вывод кода будет в формате JSON, который состоит из элементов этого URL:
{
protocols: [ 'https' ],
protocol: 'https',
port: null,
resource: 'www.stackabuse.com',
user: '',
pathname: '',
hash: '',
search: '',
href: 'https://www.stackabuse.com',
query: [Object: null prototype] {}
}
Как видите, было извлечено много вещей, хотя некоторые из них пусты, поскольку предоставленный нами URL-адрес довольно пустой. Давайте посмотрим на элементы в этом JSON:
protocols
- список протоколов, используемых в URL (может быть несколько)protocol
- первый изprotocols
port
- порт (если есть)resource
- хостuser
- пользователь на сервере хоста (user@host)pathname
- путь к ресурсуhash
- если указано, информация после#
(хеша) - обычно якоря на веб-страницеsearch
- строка запросаhref
- полный URL
Интересный пример можно найти с использованием ссылок GitHub, которые были одной из причин, по которой этот модуль был создан в первую очередь. Ссылки GitHub могут быть довольно сложными и запутанными по сравнению с другими URL-адресами, которые вы видите ежедневно, и могут включать несколько протоколов и пользователей:
const url = 'git+ssh://git@somehost.com/path/to/resource.git';
const parsedUrl = parseUrl(url);
console.log(parsedUrl)
Это приводит к:
{
protocols: [ 'git', 'ssh' ],
protocol: 'git',
port: null,
resource: 'somehost.com',
user: 'git',
pathname: '/path/to/resource.git',
hash: '',
search: '',
href: 'git+ssh://git@somehost.com/path/to/resource.git',
query: [Object: null prototype] {}
}
Список протоколов здесь изменился, поскольку используется несколько протоколов. Однако первый упоминается при распечатке информации об URL-адресе. Мы также можем видеть pathname
, теперь путь к ресурсу заполнен.
Давайте действительно увеличим URL и добавим хеш и пару запросов типа "ключ-значение":
const url = 'git+ssh://git@somehost.com:30/path/to/resource.git?key1=value1&key2=value2#anchor';
const parsedUrl = parseUrl(url);
console.log(parsedUrl)
Этот пример немного отличается от предыдущего, достаточно, чтобы заполнить пустые значения в предыдущем примере. Результатом будет:
{
protocols: [ 'git', 'ssh' ],
protocol: 'git',
port: 30,
resource: 'somehost.com',
user: 'git',
pathname: '/path/to/resource.git',
hash: 'anchor',
search: 'key1=value1&key2=value2',
href: 'git+ssh://git@somehost.com:30/path/to/resource.git?key1=value1&key2=value2#anchor',
query: [Object: null prototype] { key1: 'value1', key2: 'value2' }
}
Теперь присутствуют порт, хэш и запрос - и у нас даже есть ключи и значения для запроса! Структурирование анализируемых данных в удобочитаемом формате, который также является общепринятым и легко поддающимся синтаксическому анализу, действительно помогает при синтаксическом анализе URL-адресов.
Хотя это только красиво напечатанный вывод возвращенного объекта. Что позволяет нам действительно работать с этими проанализированными элементами, так это то, что все они являются полями возвращаемого объекта, к которым мы можем легко получить доступ:
console.log("The protocols used in the URL are " + parsedUrl.protocols);
console.log("The port used in the URL is " + parsedUrl.port);
console.log("The resource in the URL is " + parsedUrl.resource);
console.log("The user in the URL is " + parsedUrl.user);
console.log("The pathname in the URL is " + parsedUrl.pathname);
console.log("The hash in the URL is " + parsedUrl.hash);
console.log("The search part in the URL is " + parsedUrl.search);
console.log("Full URL is " + parsedUrl.href);
Выполнение этого кода приводит к:
The protocols used in the URL are git,ssh
The port used in the URL is 30
The resource in the URL is somehost.com
The user in the URL is git
The pathname in the URL is /path/to/resource.git
The hash in the URL is anchor
The search part in the URL is key1=value1&key2=value2
Full URL is git+ssh://git@somehost.com:30/path/to/resource.git?key1=value1&key2=value2#anchor
Наконец, давайте посмотрим на результаты нормализации URL. Если мы передадим ненормализованный URL-адрес, например stackabuse.com:3000/path/to/index.html#anchor
, в виде строки URL-адреса:
const url = 'stackabuse.com:3000/path/to/index.html#anchor';
const parsedUrl = parseUrl(url, true);
console.log(parsedUrl);
Это приводит к:
{
protocols: [ 'http' ],
protocol: 'http',
port: 3000,
resource: 'stackabuse.com',
user: '',
pathname: '/path/to/index.html',
hash: 'anchor',
search: '',
href: 'http://stackabuse.com:3000/path/to/index.html#anchor',
query: [Object: null prototype] {}
}
Мы видим, что парсер автоматически назначил протоколом http
и правильно заполнил свойство href
. Недостающие детали не заполняются, так как они изначально не были поставлены.
Если бы мы отключили функцию нормализации при предоставлении ненормализованного URL-адреса, результаты были бы отключены:
{
protocols: [],
protocol: 'file',
port: null,
resource: '',
user: '',
pathname: 'stackabuse.com:3000/path/to/index.html',
hash: 'anchor',
search: '',
href: 'stackabuse.com:3000/path/to/index.html#anchor',
query: [Object: null prototype] {}
}
Поскольку это объект parsedUrl
, его свойства можно изменять. Мы можем просто получить доступ к любому свойству и изменить его:
console.log(parsedUrl.port) // 3000
parsedUrl.port = 4000
console.log(parsedUrl.port) // 4000
Однако это нежелательное поведение, и его не следует делать, поскольку этот модуль используется исключительно для анализа URL-адресов. Единственный раз, когда вы должны изменять объект parsedUrl
- это когда вы уверены в ценности некоторого свойства, иначе вы можете выстрелить себе в ногу.
Заключение
Мы видели, что parse-url
позволяет нам довольно легко анализировать URL-адреса без какой-либо дополнительной обработки и делает процесс анализа URL-адресов чрезвычайно простым и читаемым.
Он разделяет все по желанию и создает объект parsedUrl
, к которому можно получить доступ, как к любому другому объекту, а также изменить. Модуль настолько прост, насколько это возможно, с аккуратным выводом и синтаксисом, а также максимально понятным, что приводит к быстрым и точным результатам.