При работе с 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 url = 'https://hexlet.io/?q=%D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3';
const { search } = new URL(url);
const qs = querystring.parse(search);
console.log(qs['?q']); // => 'эрланг'
Кроме ручного превращения строки в объект через querystring
можно воспользоваться классом URLSearchParams
:
const url = 'https://hexlet.io/?q=%D1%8D%D1%80%D0%BB%D0%B0%D0%BD%D0%B3';
const { searchParams } = new URL(url);
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
Для более полного понимания работы этих объектов и методов нужно смотреть в документацию и экспериментировать.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты