В практике разработки на платформе 1С:Предприятие 8.3 иногда возникают ситуации, которые кажутся необъяснимыми. Одна из таких проблем — случайное (рандомное) искажение данных, возвращаемых веб-сервисом. Программист видит в отладке корректную строку, но клиент получает нечитаемый набор символов или ошибку разбора XML. Проанализируем эту ситуацию, выясним причины и рассмотрим надежные способы решения.
Рассмотрим типичную ситуацию: веб-сервис формирует XML-файл (например, через типовую обработку ВыгрузкаЗагрузкаДанныхXML), записывает его на диск во временный каталог, затем считывает в строку и возвращает клиенту. В большинстве случаев это работает, но иногда клиент получает ошибку:
«Фатальная ошибка: Opening and ending tag mismatch: unknownOperation line 3 and h1»
Проанализируем этот текст. Тэг h1 — это стандартный заголовок HTML-страницы. Платформа 1С никогда не генерирует такие тэги при формировании XML. Это означает, что в какой-то момент произошел сбой, и вместо XML-данных ваш веб-сервер (IIS или Apache) вернул стандартную страницу ошибки (например, «500 Internal Server Error»). Парсер на стороне клиента пытается прочитать эту HTML-страницу как XML и закономерно выдает ошибку несоответствия тэгов.
Что касается «неизвестной кодировки» или «мусора» в файле на диске — это часто следствие того, как 1С работает с временными файлами в сеансе веб-сервиса. Если сеанс аварийно завершается или возникают проблемы с правами доступа/антивирусом, файл может быть поврежден или не дозаписан, а при попытке чтения возвращается бинарный мусор из буфера памяти.
Разберем, как выглядит проблемный код, который часто приводит к подобным ошибкам. Проблема кроется в использовании промежуточного звена — жесткого диска.
Функция GetChangedData() Экспорт
// ... формирование данных ...
КаталогОбмена = КаталогВременныхФайлов();
Путь = КаталогОбмена + "data.xml";
// Запись во временный файл
ОбработкаВыгрузки.ВыполнитьВыгрузку(Путь);
// Чтение файла в память
ЧтениеТекста = Новый ЧтениеТекста;
ЧтениеТекста.Открыть(Путь, КодировкаТекста.UTF8);
Данные = ЧтениеТекста.Прочитать();
ЧтениеТекста.Закрыть();
Возврат Данные;
КонецФункции
В этой схеме есть несколько слабых мест:
КаталогВременныхФайлов().Чтобы избежать проблем с файловой системой, проанализируем более современный подход. Начиная с версии 8.3.9, платформа 1С позволяет работать с потоками в памяти. Это исключает диск из цепочки передачи данных, что значительно повышает стабильность и скорость.
Рассмотрим пример кода, где мы используем ПотокВПамяти для формирования XML:
Функция GetDataAsStream() Экспорт
// Создаем поток в памяти
Поток = Новый ПотокВПамяти();
// Инициализируем запись XML для работы с потоком
ЗаписьXML = Новый ЗаписьXML;
ПараметрыЗаписи = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Ложь);
ЗаписьXML.ОткрытьПоток(Поток, ПараметрыЗаписи);
// Записываем данные напрямую в память
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Root");
// ... логика выгрузки объектов ...
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();
// Получаем данные из потока в виде двоичных данных
ДвоичныеДанные = Поток.ЗакрытьИПолучитьДвоичныеДанные();
// Преобразуем в строку UTF-8 для возврата через веб-сервис
Возврат ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные, КодировкаТекста.UTF8);
КонецФункции
Этот метод гарантирует, что данные не будут «перехвачены» внешними процессами ОС, и вы всегда вернете именно то, что сформировала платформа.
Иногда веб-серверы (особенно IIS с определенными модулями фильтрации) могут некорректно интерпретировать спецсимволы в XML-строке, что приводит к обрыву соединения и той самой ошибке с h1. Чтобы защитить данные от искажения при транспортировке, рекомендуется использовать кодирование Base64.
Посмотрим, как изменить возвращаемое значение:
Функция GetSafeData() Экспорт
// ... формирование XML в переменную 'Данные' ...
// Кодируем строку в Base64
Двоичные = ПолучитьДвоичныеДанныеИзСтроки(Данные, КодировкаТекста.UTF8);
СтрокаBase64 = Base64Строка(Двоичные);
Возврат СтрокаBase64;
КонецФункции
На стороне получателя (клиента) нужно будет выполнить обратное преобразование. Это гарантирует, что никакие прокси-серверы или брандмауэры не «испортят» ваш XML, так как для них это будет обычная текстовая строка в ASCII-символах.
Если проблема сохраняется даже при использовании потоков, проанализируем настройки веб-сервера. Ошибка h1 часто возникает из-за таймаутов или ограничений на размер ответа.
Для IIS выполните следующие действия:
system.webServer/security/requestFiltering/requestLimits (параметр maxAllowedContentLength).Connection Timeout в настройках сайта. Если формирование XML занимает больше минуты, IIS может разорвать соединение по своей инициативе.Dynamic Content Compression для проверки — иногда алгоритмы сжатия IIS конфликтуют с формируемыми 1С пакетами.Выясним причину ошибки быстрее, используя эти советы:
rphost. Если есть возможность, обновите платформу до актуальных релизов (8.3.22+), где работа с памятью и временными файлами более стабильна.Подведем итог. Рандомные ошибки с кодировкой и появлением HTML-тэгов в XML-ответе — это почти всегда признак «падения» рабочего процесса или вмешательства веб-сервера в передачу данных. Отказ от временных файлов в пользу потоков в памяти и использование Base64 для передачи крупных объемов данных — лучшие практики, которые сделают ваши интеграции надежными.