Как в 1С перекодировать строку в UTF-8 для отправки в веб-сервис?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними системами, например, с сайтами через API, часто возникает задача передать данные в определенной кодировке. Самый распространенный стандарт для веба — это UTF-8. Внутреннее представление строк в 1С — это UTF-16, поэтому при формировании, например, GET-запроса с кириллическими параметрами, требуется их корректно преобразовать. Разберем несколько способов, как это сделать, от простых до самых современных и правильных.

Исходная задача — пользователь вводит в 1С наименование товара, и это наименование нужно вставить в строку GET-запроса к сайту (подробнее в курсе HTTP-QUEST), предварительно перекодировав его в UTF-8.

Когда и зачем нужна перекодировка в 1С?

Прежде чем переходить к решениям, давайте проясним, в каких случаях вообще требуется задумываться о кодировках. Платформа 1С берет на себя много рутинных операций, но при обмене данными с внешним миром контроль остается за разработчиком. Перекодировка строки может понадобиться в следующих ситуациях:

  1. Запись и чтение файлов: при создании файлов (.txt, .csv, .xml) для обмена. Для сложной трансформации данных удобно использовать модуль «Трансформер».
  2. HTTP-запросы: при передаче данных в теле POST-запроса или в параметрах GET-запроса к API (для отладки и визуального контроля пригодится инструмент логирования и анализа HTTP-запросов в 1С). Для разработки таких интерфейсов часто применяют конструкторы API.
  3. Работа с двоичными данными: когда строку необходимо преобразовать в поток байтов для дальнейшей обработки, например, для подписи RSA с хешированием или для формирования пакета данных по низкоуровневому протоколу.

В нашем случае — это формирование HTTP-запроса. Посмотрим, какими инструментами мы можем решить эту задачу.

Решение 1: Использование временного файла

Это один из самых старых и понятных, но не самых эффективных способов. Идея проста: мы сохраняем нашу строку во временный файл в одной кодировке, а затем читаем из этого же файла, но уже указывая другую, нужную нам кодировку. Все операции по преобразованию байтов выполнит сама платформа 1С при файловых операциях.

Рассмотрим готовую функцию, которая инкапсулирует эту логику:


// Возвращает перекодированную строку
// ИсходнаяКодировка - кодировка строки, которую мы подаем на вход.
//                      Для стандартных строк 1С можно не указывать, но важно при чтении из внешних источников.
// КонечнаяКодировка - кодировка, которую мы хотим получить на выходе.
Функция ПерекодироватьСтрокуЧерезФайл(СтрокаДляПерекодировки, ИсходнаяКодировка = "windows-1251", КонечнаяКодировка = "UTF-8") Экспорт
    
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
    
    // Этап 1: Записываем строку в файл в исходной кодировке
    ЗаписьТекста = Новый ЗаписьТекста;
    ЗаписьТекста.Открыть(ИмяВременногоФайла, ИсходнаяКодировка);
    ЗаписьТекста.Записать(СтрокаДляПерекодировки);
    ЗаписьТекста.Закрыть();
    
    // Этап 2: Читаем из этого же файла, но указываем конечную кодировку
    ЧтениеТекста = Новый ЧтениеТекста(ИмяВременногоФайла, КонечнаяКодировка);
    Результат = ЧтениеТекста.Прочитать();
    ЧтениеТекста.Закрыть();
    
    // Этап 3: Не забываем убрать за собой
    УдалитьФайлы(ИмяВременногоФайла);
    
    Возврат Результат;
    
КонецФункции // ПерекодироватьСтрокуЧерезФайл

Плюсы этого метода:

Минусы:

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

Решение 2: Использование COM-объекта (Windows-only)

Более производительный, чем файловый, способ — использование внешнего COM-объекта Adodb.Stream. Он позволяет выполнять операции с данными в памяти, без обращения к жесткому диску. Этот метод долгое время был популярен для подобных задач.


// Перекодирует текст с использованием COM-объекта Adodb.Stream
// ВНИМАНИЕ: Этот метод будет работать только на ОС Windows.
&НаСервереБезКонтекста
Функция ПерекодироватьТекстCOM(КодируемыйТекст, НачальнаяКодировка = "utf-8", КонечнаяКодировка = "windows-1251")
    
    Попытка
        Стрим = Новый COMОбъект("Adodb.Stream");
    Исключение
        ВызватьИсключение "Не удалось создать COM-объект 'Adodb.Stream'. " +
        "Возможно, компонент не зарегистрирован в системе или код выполняется на сервере Linux.";
    КонецПопытки;
    
    Стрим.Type = 2; // adTypeText - текстовый тип данных
    Стрим.Mode = 3; // adModeReadWrite - чтение и запись
    Стрим.charset = НачальнаяКодировка;
    Стрим.Open();
    Стрим.WriteText(КодируемыйТекст);
    
    // Перемещаем указатель в начало потока для чтения
    Стрим.Position = 0;
    Стрим.charset = КонечнаяКодировка; // Устанавливаем кодировку для чтения
    
    ПерекодированныйТекст = Стрим.ReadText(-1); // -1 = adReadAll - прочитать все
    Стрим.Close();
    
    Возврат ПерекодированныйТекст;
    
КонецФункции

Плюсы:

Минусы:

Решение 3: Современный способ через потоки в памяти

Это самый правильный и рекомендуемый способ перекодировки строк в современных версиях платформы 1С. Он использует встроенные объекты для работы с данными в памяти: ПотокВПамяти, ЗаписьДанных и ЧтениеТекста. Метод кроссплатформенный, быстрый и не имеет внешних зависимостей.

Логика похожа на работу с файлом, но все действия происходят в оперативной памяти.


// Перекодирует текст с использованием нативных потоков 1С
// Это наиболее универсальный и рекомендуемый способ
Функция ПерекодироватьТекст(КодируемыйТекст, НачальнаяКодировка = "windows-1251", КонечнаяКодировка = "utf-8")
    
    // 1. Создаем поток в памяти для временного хранения данных
    Поток = Новый ПотокВПамяти;
    
    // 2. Записываем в него исходную строку, указывая ее кодировку
    //    Для строк, созданных внутри 1С, начальная кодировка - UTF16,
    //    но платформа справится с преобразованием из стандартной строки.
    //    Указывать начальную кодировку важно, если вы получили строку извне.
    ЗаписьДанных = Новый ЗаписьДанных(Поток);
    ЗаписьДанных.УстановитьКодировкуТекста(НачальнаяКодировка);
    ЗаписьДанных.ЗаписатьСимволы(КодируемыйТекст);
    ЗаписьДанных.Закрыть();
    
    // 3. Получаем из потока двоичные данные
    ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    
    // 4. Открываем поток для чтения из этих двоичных данных
    ПотокЧтения = ДвоичныеДанные.ОткрытьПотокДляЧтения();
    
    // 5. Читаем текст из потока, указывая нужную нам конечную кодировку
    ЧтениеТекста = Новый ЧтениеТекста(ПотокЧтения, КонечнаяКодировка);
    СтрокаВозврата = ЧтениеТекста.Прочитать();
    ЧтениеТекста.Закрыть();
    
    Возврат СтрокаВозврата;
    
КонецФункции

Плюсы:

Это лучший выбор для большинства задач по перекодировке.

Специальный случай: Кодирование для URL (GET-запросы)

Вернемся к нашей первоначальной задаче: нужно передать наименование товара в GET-запросе. Здесь есть важный нюанс. Просто перекодировать строку в UTF-8 недостаточно. По стандарту, URL-адреса могут содержать только ограниченный набор символов. Все остальные, включая кириллицу, пробелы и спецсимволы, должны быть представлены в специальном "процентном" виде (Percent-encoding). Например, пробел заменяется на %20, а буква "А" (кириллическая) — на %D0%90.

К счастью, для этой задачи в 1С есть специальная встроенная функция — КодироватьСтроку().


НаименованиеТовара = "Товар: Чайник 'Bosch' (красный)";

// Правильное кодирование строки для URL
ЗакодированнаяСтрока = КодироватьСтроку(НаименованиеТовара, СпособКодированияСтроки.URL);

// ЗакодированнаяСтрока будет содержать что-то вроде:
// "Товар%3A%20Чайник%20'Bosch'%20(красный)" 
// (фактическое представление кириллицы будет сложнее, например %D0%A2%D0%BE%D0%B2%D0%B0%D1%80...)

// Формируем итоговый URL
АдресСервиса = "https://my-site.com/api/get_item?name=";
ИтоговыйURL = АдресСервиса + ЗакодированнаяСтрока;

Функция КодироватьСтроку с параметром СпособКодированияСтроки.URL делает именно то, что нужно: она берет исходную строку, преобразует ее символы в байты по стандарту UTF-8, а затем кодирует эти байты в процентный формат. Это самый простой, быстрый и правильный способ подготовки параметров для GET-запросов.

Итог

Давайте подведем итог и выберем правильный инструмент для каждой задачи:

  1. Если вам нужно подготовить строку для вставки в URL-адрес (GET-запрос) — ваш выбор однозначно КодироватьСтроку(Строка, СпособКодированияСтроки.URL).
  2. Если вам нужно выполнить общую перекодировку строки (например, из windows-1251 в UTF-8) для записи в файл или для тела POST-запроса — используйте современный метод с потоками в памяти. Он самый надежный и производительный.
  3. Методы с использованием временного файла и COM-объекта лучше избегать и использовать только в крайних случаях, например, при работе с очень старыми конфигурациями или при отсутствии альтернатив.
← На главную