Интеграция 1С с внешними веб-сервисами через HTTP-запросы — одна из самых частых задач современного разработчика. Однако даже при правильной логике формирования JSON-пакета можно столкнуться с ошибкой 400 Bad Request. В этой статье мы подробно разберем, почему сервер может отклонять корректный на первый взгляд запрос, как бороться с невидимыми символами в строках и как эффективно передавать файлы через протокол HTTP.
Рассмотрим ситуацию: вы создали обработку, настроили HTTPСоединение, сформировали JSON-структуру, но при отправке метода POST сервер возвращает ошибку. В теле ответа от сервера (например, Alfresco или другого API) можно увидеть сообщение: Unexpected character ('' (code 65279 / 0xfeff)). Этот код (65279) соответствует символу BOM (Byte Order Mark).
Проанализируем причину: 1С при использовании кодировки UTF-8 по умолчанию может добавлять в начало строки специальный префикс, указывающий на порядок байтов. Большинство современных REST-сервисов ожидают «чистый» JSON и воспринимают этот символ как синтаксическую ошибку в самом начале потока данных.
Для решения этой проблемы в методе УстановитьТелоИзСтроки объекта HTTPЗапрос предусмотрен специальный параметр. Давайте посмотрим на правильный пример формирования запроса:
// Формируем структуру данных
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("target", Новый Структура("file", Новый Структура("guid", "abcde-01234")));
// Сериализуем в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
СтрокаJSON = ЗаписьJSON.Закрыть();
// Подготовка запроса
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
Запрос = Новый HTTPЗапрос("/api/v1/nodes", Заголовки);
// ВНИМАНИЕ: Третий параметр Ложь отключает добавление BOM
Запрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Использование перечисления ИспользованиеByteOrderMark.НеИспользовать гарантирует, что в тело запроса попадет только текст JSON без лишних технических символов в начале. Это исправляет ошибку 400 в большинстве случаев взаимодействия с веб-сервисами.
Часто после создания объекта в системе (через POST) требуется загрузить его содержимое. API может требовать передачу двоичных данных файла напрямую в теле запроса (метод PUT). Рассмотрим ситуацию, когда адрес ресурса выглядит как /nodes/{id}/content.
Существует распространенное заблуждение, что файл нужно обязательно кодировать в Base64. Однако, если документация API указывает, что в теле передается «двоичное содержимое», то передавать нужно именно поток байтов. Это гораздо эффективнее с точки зрения производительности и расхода оперативной памяти.
Выясним, как это реализовать в 1С. Вместо загрузки всего файла в строку, мы воспользуемся методом УстановитьИмяФайлаТела. Это позволит платформе 1С передать файл прямо с диска в HTTP-канал.
// Путь к файлу на диске
ПутьКФайлу = "C:\Files\document.pdf";
// Настройка соединения
Соединение = Новый HTTPСоединение("api.service.com", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
// Формируем запрос для загрузки контента
Ресурс = "/alfresco/api/-default-/public/alfresco/versions/1/nodes/" + ИдентификаторНоды + "/content";
Заголовки = Новый Соответствие;
// Указываем тип контента, соответствующий файлу
Заголовки.Вставить("Content-Type", "application/octet-stream");
Запрос = Новый HTTPЗапрос(Ресурс, Заголовки);
// Указываем путь к файлу. Платформа сама прочитает его и отправит в теле
Запрос.УстановитьИмяФайлаТела(ПутьКФайлу);
// Выполняем PUT запрос
Результат = Соединение.ВызватьHTTPМетод("PUT", Запрос);
Если Результат.КодСостояния = 200 Тогда
Сообщить("Файл успешно загружен!");
КонецЕсли;
Для стабильной работы обменов рекомендуем придерживаться следующих правил:
ОтправитьДляОбработки или Получить, старайтесь использовать ВызватьHTTPМетод. Это позволяет легко менять тип запроса (POST, PUT, PATCH, DELETE) без переписывания структуры кода.ЗащищенноеСоединениеOpenSSL. На клиентских местах это позволяет 1С использовать системные сертификаты Windows для проверки подлинности сервера.КодСостояния отличается от 200 или 201, обязательно считывайте тело ответа методом Результат.ПолучитьТелоКакСтроку(). Обычно там содержится подробное описание ошибки от разработчиков API (например, «недостаточно прав» или «неверный формат поля»).HTTPСоединение (параметр Таймаут). По умолчанию он может быть слишком мал для загрузки файлов весом более 10-20 МБ.Проанализировав эти подходы, мы видим, что 1С обладает всеми необходимыми инструментами для работы с современными RESTful сервисами. Главное — внимательно следить за кодировками и правильно выбирать способ передачи данных (строка или файл), исходя из требований конкретного API.