При интеграции 1С с внешними информационными системами (например, ГИС ТКО или сервисами ППК РЭО) разработчики часто сталкиваются с ситуацией, когда запрос возвращает ошибки 415 Unsupported Media Type или 422 Unprocessable Entity. В этой статье мы подробно разберем причины возникновения этих ошибок на примере реального кейса, проанализируем типичные ошибки при формировании JSON и выясним, как правильно передавать данные в формате multipart/form-data.
Рассмотрим ситуацию, когда разработчик пытается преобразовать структуру 1С в текст для отправки. Одной из самых распространенных ошибок является использование встроенной функции Строка(). Давайте проанализируем, что происходит в коде:
// ОШИБОЧНЫЙ КОД
Данные = Новый Структура;
Данные.Вставить("objectId", "ce0dec40-5f72-447c-9d5e-abe4bebffdaa");
// ... заполнение данных ...
СтрокаДанных = Строка(Данные);
// В переменную СтрокаДанных попадет текст "Структура", а не содержимое полей!
В системе 1С функция Строка() для объекта типа Структура возвращает лишь строковое представление типа объекта. В результате на сервер уходит текст "Структура", который не является валидным JSON-объектом. Это гарантированно приведет к ошибке 422 (если сервер ожидал JSON, но получил неверный формат) или ошибке парсинга на стороне принимающего шлюза.
Для правильного преобразования данных в формат JSON необходимо использовать объект ЗаписьJSON. Разберем правильный подход:
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, Данные);
РезультатJSON = ЗаписьJSON.Закрыть();
// Теперь в РезультатJSON действительно находится валидная JSON-строка
Проанализируем еще одну критическую ошибку. В попытках отправить файл через MSXML2.XMLHTTP, разработчики часто копируют синтаксис консольной утилиты curl, указывая символ @ перед путем к файлу:
Запрос.send("file=@" + ПутьКФайлу);
Важно понимать: COM-объекты Windows или стандартные объекты 1С (HTTPЗапрос) не умеют интерпретировать символ @ как команду «прочитать файл с диска». Они воспринимают это выражение как обычную текстовую строку. В итоге сервер получает не содержимое файла, а просто путь к нему (который ему бесполезен), что снова вызывает ошибку 422, так как данные не прошли валидацию.
Если спецификация API (как в случае с ГИС ТКО) требует использования multipart/form-data, это означает, что данные должны передаваться не в виде «чистого» JSON в теле запроса, а как часть сложной многокомпонентной формы. Ошибка 415 как раз указывает на то, что вы пытаетесь отправить application/json там, где сервер ждет составную форму.
Рассмотрим, как правильно сформировать такой запрос. Современная платформа 1С (начиная с 8.3.10) предоставляет для этого удобные инструменты. Вместо ручной сборки границ (boundary), мы можем использовать метод СформироватьТелоСМногокомпонентнымиДанными объекта HTTPЗапрос.
Выясним, как это реализовать пошагово:
file).
// 1. Формируем JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
СтрокаJSON = ЗаписьJSON.Закрыть();
// 2. Подготавливаем HTTP запрос
Граница = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
Запрос = Новый HTTPЗапрос("/api/v1/upload");
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Граница);
// 3. Формируем тело запроса
Разделитель = "--" + Граница;
Тело = Новый ПотокВПамяти;
ЗаписьТекста = Новый ЗаписьТекста(Тело, КодировкаТекста.UTF8);
ЗаписьТекста.ЗаписатьСтроку(Разделитель);
// Имя "file" должно соответствовать требованиям документации API
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""file""; filename=""data.json""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: application/json");
ЗаписьТекста.ЗаписатьСтроку(""); // Пустая строка перед данными
ЗаписьТекста.ЗаписатьСтроку(СтрокаJSON);
ЗаписьТекста.ЗаписатьСтроку(Разделитель + "--");
ЗаписьТекста.Закрыть();
Запрос.УстановитьТелоИзПотока(Тело);
Если формат запроса исправлен (используется multipart/form-data), а JSON сформирован корректно, но сервер все равно возвращает 422 Unprocessable Entity, значит проблема кроется в содержимом данных. Проанализируем типичные причины для систем учета (например, весового контроля):
"weightBefore": 8980 (число), а вы отправляете "weightBefore": "8980" (строка в кавычках), валидация не пройдет.YYYY-MM-DDTHH:mm:ss.null или где поле должно вовсе отсутствовать.id (УИД операции) часто блокируется сервером с кодом 422.Для того чтобы точно понять, что именно уходит из 1С на сервер, мы рекомендуем использовать прокси-отладчики, такие как Fiddler или Charles. Настройте 1С на работу через прокси:
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("http", "127.0.0.1", 8888); // Порт Fiddler
Соединение = Новый HTTPСоединение("api.server.ru",,,, Прокси);
Проанализировав "сырой" HTTP-трафик, вы сразу увидите, действительно ли там JSON или просто слово "Структура", а также правильно ли расставлены границы boundary в многокомпонентном запросе.
Подводя итог, отметим, что успешная интеграция зависит от трех факторов: правильной сериализации через ЗаписатьJSON, корректного указания Content-Type и строгого соблюдения типов данных (числа как числа, даты в ISO-формате), требуемых внешней системой.