При интеграции платформы 1С с внешними веб-сервисами разработчики часто сталкиваются с труднообъяснимыми ошибками. Вроде бы структура JSON сформирована идеально, кодировка UTF-8 соблюдена, параметры передаются корректно, но удаленный сервер упорно возвращает ошибку в духе "Invalid JSON format" или "Bad Request". В этой статье мы подробно разберем одну из самых коварных проблем веб-интеграции — влияние метки порядка байтов (BOM — Byte Order Mark) на парсинг запросов внешними системами, проанализируем поведение платформы 1С разных версий и выработаем надежные решения для обхода этой проблемы.
Давайте разберем ситуацию на примере интеграции с сервисом Zoho Books. Большинство современных REST API принимают данные в формате JSON напрямую в теле запроса (Request Body). Однако Zoho Books v3 спроектирован по классической схеме веб-форм. Он ожидает данные в формате multipart/form-data или application/x-www-form-urlencoded, где сам JSON передается внутри текстового параметра с именем JSONString. Таким образом, сырое тело POST-запроса должно выглядеть следующим образом:
JSONString={"item_name": "Товар из 1С", "rate": 100}
Проблема заключается в том, что при записи строки в UTF-8 платформа 1С по умолчанию может добавлять в начало файла или потока специальную сигнатуру — **BOM (Byte Order Mark)**. Для кодировки UTF-8 это невидимая последовательность из трех байтов: 0xEF, 0xBB, 0xBF.
Когда сервер принимает такой поток, его внутренний парсер видит в самом начале запроса не ожидаемый символ "J", а эти три невидимых байта: \xef\xbb\xbfJSONString=.... Для строгого парсера API Zoho Books имя параметра искажается, из-за чего система либо вообще не находит ключ JSONString, либо выдает синтаксическую ошибку парсинга JSON, сбивая разработчика с толку.
Давайте выясним причину, почему интеграция может внезапно сломаться после обновления платформы или изменения настроек конфигурации. Дело в том, что поведение платформы 1С в отношении BOM напрямую зависит от используемой версии и установленного режима совместимости:
Таким образом, если ваша база работала на старом режиме совместимости, а затем вы перевели ее на актуальный режим (или обновили платформу), поведение методов работы с HTTP-запросами могло измениться, нарушив обратную совместимость с внешними веб-сервисами.
Для того чтобы гарантировать отсутствие невидимых мусорных байтов в начале вашего HTTP-запроса, необходимо явно управлять записью BOM. В современных версиях платформы 1С 8.3 для объекта HTTPЗапрос предусмотрен метод УстановитьТелоИзСтроки(), третьим параметром которого выступает системное перечисление ИспользованиеByteOrderMark.
Давайте посмотрим на пример правильного формирования и отправки POST-запроса с принудительным отключением BOM:
// Шаг 1. Формируем чистую строку JSON без лишних пробелов
ДанныеДляОтправки = Новый Структура;
ДанныеДляОтправки.Вставить("item_name", "Номенклатура из 1С");
ДанныеДляОтправки.Вставить("rate", 1500);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеДляОтправки);
СтрокаJSON = ЗаписьJSON.Закрыть();
// Шаг 2. Формируем тело запроса для Zoho API (с префиксом параметра)
ТелоHTTPЗапроса = "JSONString=" + СтрокаJSON;
// Шаг 3. Создаем HTTP-запрос и устанавливаем заголовки
HTTPЗапрос = Новый HTTPЗапрос("/api/v3/items");
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
// Шаг 4. Явно указываем ИспользованиеByteOrderMark.НеИспользовать
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоHTTPЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// Шаг 5. Отправляем запрос через HTTPСоединение
HTTPСоединение = Новый HTTPСоединение("books.zoho.com", 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL());
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Использование свойства ИспользованиеByteOrderMark.НеИспользовать полностью решает проблему, гарантируя, что удаленный сервер получит чистый поток байтов UTF-8 без невидимых префиксов в заголовке тела.
Если вам приходится поддерживать старые конфигурации, работающие на платформе 1С 8.2 или в режимах совместимости, где у метода УстановитьТелоИзСтроки() еще не было параметра управления BOM (или самого этого метода не существовало), придется использовать обходные пути.
Способ 1. Использование временного файла через ЗаписьТекста
Объект ЗаписьТекста в 1С позволяет очень гибко управлять кодировками и BOM. Мы можем записать тело запроса в файл без BOM, а затем прочитать этот файл как двоичные данные:
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
// Четвертый параметр конструктора ЗаписьТекста (Ложь) отключает использование BOM для UTF-8
ЗаписьТекста = Новый ЗаписьТекста(ИмяВременногоФайла, КодировкаТекста.UTF8, , Ложь);
ЗаписьТекста.ЗаписатьСтроку(ТелоHTTPЗапроса);
ЗаписьТекста.Закрыть();
// Считываем «чистые» двоичные данные из временного файла
ДвоичныеДанныеТела = Новый ДвоичныеДанные(ИмяВременногоФайла);
// Помещаем двоичные данные в HTTP-запрос
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеТела);
// Не забываем удалить временный файл после отправки
УдалитьФайлы(ИмяВременногоФайла);
Способ 2. Использование кодировки CESU-8
В некоторых специфических сценариях для обхода ограничений старых парсеров разработчики использовали кодировку CESU-8. Она очень близка к UTF-8, но по своей специфике не предполагает использование сигнатуры BOM. Однако этот метод является компромиссным и может поддерживаться не всеми веб-сервисами.
Выявить наличие BOM в теле запроса "вслепую" в коде 1С практически невозможно, так как при чтении строки отладочные инструменты 1С просто игнорируют или скрывают эти служебные символы. Для успешного расследования подобных проблем рекомендуется применять специализированные инструменты:
httpbin.org/post. В ответ такой сервис пришлет полную копию вашего запроса в том виде, в котором он пришел на сервер. Анализируя структуру возвращенных данных, вы легко заметите искажение имен ключей или неожиданные символы перед началом полезной нагрузки.EF BB BF. Если они есть — BOM активен и его нужно отключать.Важная рекомендация: Всегда явно указывайте параметры кодирования и использования BOM при интеграции со сторонними информационными системами. Это убережет ваши решения от внезапных сбоев при обновлении технологической платформы 1С.