Node.js LinuxWindowsNode.js

Node.js: Node.js неправильно обрабатывает Unicode в потоке данных

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

Кириллица и другие символы иногда превращаются в �, когда граница потока разрезает многобайтовый символ UTF-8, а код самостоятельно вызывает chunk.toString() для каждого отдельного Buffer.

В этой статье
  1. Симптомы и условия возникновения
  2. Причины и как их отличить
  3. Пошаговая диагностика и решение
  4. Как проверить результат и что делать, если не помогло

#Симптомы и условия возникновения

Кириллица и другие символы иногда превращаются в �, когда граница потока разрезает многобайтовый символ UTF-8, а код самостоятельно вызывает chunk.toString() для каждого отдельного Buffer. Для начала проверьте используемую версию среды и точный текст ошибки на копии проекта, не меняя рабочий сервер.

#Причины и как их отличить

Возможная причинаКак узнатьЧто делать
Порционная декодировкаВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление.Искажение зависит от размера частей, в файле байты верныеИспользовать потоковый декодер с сохранением неполных байтов.
Реальная кодировка не UTF-8В этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление.Даже при чтении целого файла текст испорченОпределить исходную кодировку и конвертировать отдельно.
Двойное декодированиеВ этой ситуации наблюдается конкретный диагностический признак. Сопоставьте его с журналом ошибки и результатом соответствующей проверки, прежде чем выбирать исправление.В журнале видны последовательности вида ÐУстановить точное место ошибочной конвертации.

#Пошаговая диагностика и решение

  1. 1. Проверьте один и тот же входной файлСделайте копию файла с кириллицей. Просмотрите оригинал в редакторе с явно выбранной UTF-8; если он уже неверен, потоковый декодер не восстановит утраченные символы.
  1. 2. Найдите опасное преобразованиеВ проекте найдите обработчики stream.on("data", chunk => chunk.toString("utf8")). Отдельный Buffer может заканчиваться в середине символа, поэтому каждый chunk нельзя декодировать изолированно.
  1. 3. Используйте setEncoding для читаемого потокаЕсли вход действительно UTF-8, сразу после createReadStream вызовите .setEncoding("utf8"). Node сохранит неполные байты между порциями; в обработчик data начнут поступать строки.
  1. 4. При ручной декодировке используйте StringDecoderВ потоке Buffer создайте new StringDecoder("utf8"), передавайте каждую порцию в decoder.write() и в конце вызовите decoder.end(). Не создавайте новый StringDecoder на каждой порции.
  1. 5. Проверьте границу символа на искусственном примереВ тестовом файле создайте пример с разделёнными байтами евро или кириллической буквы, сравните отдельный Buffer.toString и StringDecoder. Корректный декодер выдаёт единственный исходный символ.
  1. 6. Уточните HTTP-кодировку и выводЕсли проблема только при ответе браузеру, проверьте Content-Type: text/plain; charset=utf-8 и отсутствие второй перекодировки; настройка заголовка не исправляет неправильные байты.
  1. 7. Прогоните контрольные строкиПроверьте русские слова, emoji и латиницу, в том числе когда входные части имеют разные размеры. Если остаются �, изучите реальные байты источника и его объявленную кодировку.
  2. Самостоятельный тест в файле .mjs, запускаемый командой node test.mjs
    Текст
    Самостоятельный тест в файле .mjs, запускаемый командой node test.mjs.
    import { StringDecoder } from 'node:string_decoder';
    const decoder = new StringDecoder('utf8');
    const a = Buffer.from([0xD0]);
    const b = Buffer.from([0x96]); // Вместе байты «Ж»
    console.log(decoder.write(a) + decoder.write(b) + decoder.end()); // Ж

#Как проверить результат и что делать, если не помогло

Текст совпадает с исходным побайтно после обратной кодировки в UTF-8, а кириллица и emoji не превращаются в символ замены при произвольных размерах частей.

Если неисправность повторилась, выпишите первый код ошибки и действие, на котором она возвращается. Сравните версию Node.js/npm, рабочий каталог, настройки процесса и журнал тестового запуска. Откатите только внесённые изменения из предварительно сохранённой копии, затем разберите причину на отдельной среде.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.