TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Настя Котова // Frontend & Node.js

24 Aug, 18:25

Открыть в Telegram Поделиться Пожаловаться

Весной мы обсуждали работу с сырыми данными: ArrayBuffer, Buffer в Node.js, SharedArrayBuffer и Blob. Но кое-какие инструменты мы тогда не обсудили, а именно TextEncoder и TextDecoder, пару, которая переводит строки в байты и обратно.

API у них достаточно простое: у одного есть encode(), у другого decode(). Однако своих нюансов в их работу добавляет то, что строки в JavaScript хранятся в UTF-16, а данные вокруг (файлы, сеть и т.д.) почти всегда в UTF-8. Поэтому TextEncoder умеет кодировать только в UTF-8, и других вариантов у него нет, а вот TextDecoder принимает десятки кодировок.

Дальше начинаются суррогатные пары. Символы выше U+FFFF (эмодзи, редкие иероглифы, некоторые математические знаки) не помещаются в один 16-битный код и хранятся как два. Отдельного внимания заслуживает случай, когда суррогат остался без пары, например, строку обрезали ровно посередине символа. Тогда TextEncoder заменит его на U+FFFD (тот самый знаменитый �) и не выбросит никакого исключения.

Дело в том, что в спецификации encode() принимает USVString — строку, в которой суррогатов не бывает по определению. Обычные JS-строки — это DOMString, и при передаче аргумента происходит конвертация одного в другое, при которой каждый одинокий суррогат и заменяется. Таким образом до самого кодировщика битая строка уже не доходит.

Похожая тихая механика, без всяких ошибок, есть и у BOM — метки порядка байтов U+FEFF, которую любят добавлять в начало файла редакторы под Windows. По умолчанию TextDecoder её срезает, и в результирующей строке она не появляется. Опция ignoreBOM работает противоположно тому, что можно предположить по названию: она означает не «игнорировать метку», а «не обрабатывать её специальным образом», то есть оставить в строке как обычный символ.

Последний нюанс касается потокового чтения. Если данные приходят чанками, многобайтовый символ вполне может оказаться разрезанным на границе. Стандартный вызов декодера посчитает такую последовательность некорректной и выдаст всё тот же символ �. Однако если передать { stream: true }, то декодер сохранит незавершённый хвост до следующего вызова, а финальный decode() без аргументов сбросит остаток.


const decoder = new TextDecoder();
decoder.decode(chunk, { stream: true });
decoder.decode();

1.5k 0 8 4 19
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot