JS: Синхронная асинхронность

URL

При работе с http возникает потребность в библиотеках, позволяющих манипулировать частями адресов, разбирать их, а так же собирать обратно. Node.js предоставляет такие модули из коробки.

Url

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

import url from 'url';

const { URL } = url;

const parsedURL = new URL('http://user:pass@host.com:8080/p/a/t/h?query=string#hash');
// URL {
//   href: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash',
//   origin: 'http://host.com:8080',
//   protocol: 'http:',
//   username: 'user',
//   password: 'pass',
//   host: 'host.com:8080',
//   hostname: 'host.com',
//   port: '8080',
//   pathname: '/p/a/t/h',
//   search: '?query=string',
//   searchParams: URLSearchParams { 'query' => 'string' },
//   hash: '#hash'
// }

То же самое можно визуализировать:

┌─────────────────────────────────────────────────────────────────────────────┐
│                                    href                                     │
├──────────┬┬───────────┬─────────────────┬───────────────────────────┬───────┤
│ protocol ││   auth    │      host       │           path            │ hash  │
│          ││           ├──────────┬──────┼──────────┬────────────────┤       │
│          ││           │ hostname │ port │ pathname │     search     │       │
│          ││           │          │      │          ├─┬──────────────┤       │
│          ││           │          │      │          │ │    query     │       │
"  http:   // user:pass @ host.com : 8080   /p/a/t/h  ?  query=string   #hash "
│          ││           │          │      │          │ │              │       │
└──────────┴┴───────────┴──────────┴──────┴──────────┴─┴──────────────┴───────┘

    (all spaces in the "" line should be ignored -- they're purely for formatting)

Как видно, этот модуль дал нам возможность извлечь query params из адреса, но в виде строки. Дальше, как вы уже догадались, нам понадобится еще один модуль - querystring.

Querystring

Он также входит в поставку Node.js и работает очень просто:

import querystring from 'querystring';

const str = 'w=%D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3&foo=bar';

querystring.parse(str);
// { w: 'эрланг', foo: 'bar' }

querystring.stringify({ w: 'эрланг', foo: 'bar' });
// w=%D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3&foo=bar

Здесь необходимо сделать пояснение. Спецификация http разрешает использовать в адресах только те символы, которые входят в ASCII character-set. Возникает вопрос: как быть, если у нас есть другие символы? А для этого применяется специальное кодирование, называемое url encoding. Например, слово скрипт будет закодировано в строку: %D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82.

Модуль querystring делает кодирование/декодирование автоматически, это видно в примере выше. Но если вам вдруг понадобилось делать это руками, то js спешит на помощь:

encodeURI('эрланг');
// %D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3

decodeURI('%D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3');
// эрланг

А теперь собираем все вместе:

import querystring from 'querystring';

const uri = 'https://hexlet.io/?q=%D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3';
const { search } = new URL(uri);
const qs = querystring.parse(search);
console.log(qs['?q']); // => 'эрланг'

Кроме ручного превращения строки в объект через querystring можно воспользоваться классом URLSearchParams:

const uri = 'https://hexlet.io/?q=%D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3';
const { searchParams } = new URL(uri);
const query = Object.fromEntries(searchParams); // превращение в объект
console.log(query); // => { q: 'эрланг' }

Обратная задача – конструирование адреса выполняется через создание объекта URL и его наполнение:

const url = new URL('/my', 'https://hexlet.io');
url.searchParams.set('page', 5);
console.log(url.toString()); // https://hexlet.io/my?page=5

Для более полного понимания работы этих объектов и методов нужно смотреть в документацию и экспериментировать.


Дополнительные материалы

  1. Документация по URL
  2. Документация по querystring
  3. Документация по URLSearchParams

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».