При интеграции 1С с внешними веб-сервисами программисты часто сталкиваются с ситуацией, когда запрос, который казалось бы настроен верно, возвращает ошибку HTTP 400 Bad Request. В отличие от ошибок авторизации (401 или 403), код 400 указывает на то, что сервер «не понимает» ваш запрос из-за некорректного синтаксиса или отсутствия обязательных данных. Рассмотрим подробнее, как правильно сконструировать POST-запрос в среде «1С:Предприятие 8», чтобы избежать подобных проблем.
Прежде чем приступать к написанию кода, проанализируем ситуацию. Если сервер возвращает 400, это означает, что соединение установлено, адрес (URL) найден, но содержимое пакета данных не соответствует ожиданиям веб-сервиса. Основными причинами в контексте 1С являются:
{}.Для того чтобы сервер корректно обработал наш POST-запрос, мы должны явно указать тип передаваемого контента. Выясним, какие заголовки являются критически важными. Мы будем использовать объект HTTPЗапрос.
Посмотрим на пример установки базовых заголовков:
Запрос = Новый HTTPЗапрос(Ресурс);
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.Заголовки.Вставить("Accept", "application/json");
Заголовок Content-Type сообщает серверу, что данные в теле запроса — это JSON в кодировке UTF-8. Заголовок Accept указывает, что в ответ мы также ожидаем получить данные в формате JSON. Это стандарт вежливости в HTTP-протоколе, который минимизирует вероятность ошибок интерпретации данных.
Одной из самых коварных проблем 1С является добавление BOM при преобразовании строки в двоичные данные. Рассмотрим, как гарантированно отправить «чистый» JSON. Для этого в методе УстановитьТелоИзСтроки() необходимо использовать параметры управления кодировкой.
Проанализируем пример кода:
ТекстJSON = "{""action"": ""getData"", ""id"": 123}"; // Пример простого JSON
// В новых версиях платформы (начиная с 8.3.10)
// Используем ИспользованиеByteOrderMark.НеИспользовать
Запрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Если ваша версия платформы не поддерживает ИспользованиеByteOrderMark, мы рекомендуем использовать объект ЗаписьJSON вместе с потоками в памяти, чтобы полностью контролировать процесс записи байтов. Это исключит ситуацию, когда сервер выдает ошибку 400 из-за того, что первым символом в пакете пришел невидимый технический код, а не открывающая фигурная скобка {.
Если сервер требует авторизации, а вы получаете 400, убедитесь, что заголовок Authorization сформирован верно. В случае Basic Authorization данные (логин и пароль) должны быть закодированы в формат Base64. Посмотрим, как это реализовать программно:
Логин = "admin";
Пароль = "password123";
ДанныеАвторизации = Логин + ":" + Пароль;
// Преобразуем строку в Base64 через двоичные данные
ДвоичныеДанныеАвторизации = ПолучитьДвоичныеДанныеИзСтроки(ДанныеАвторизации, КодировкаТекста.UTF8, Ложное);
СтрокаBase64 = Base64Строка(ДвоичныеДанныеАвторизации);
Запрос.Заголовки.Вставить("Authorization", "Basic " + СтрокаBase64);
Важный момент: Обратите внимание на пробел после слова Basic. Его отсутствие — частая причина того, что сервер не может распарсить заголовок и возвращает ошибку 400.
Теперь соберем все части воедино. Мы создадим объект HTTPСоединение, учитывая требования безопасности (использование SSL), и отправим наш запрос. Для работы с защищенным соединением (HTTPS) обязательно используем объект ЗащищенноеСоединениеOpenSSL.
Подобный программный код часто применяется там, где требуется интеграция с облачным сервисом, например, T-Cloud. Рассмотрим полный цикл отправки запроса:
// Настройки подключения
Сервер = "api.example.com";
Порт = 443;
ИспользоватьSSL = Истина;
// Создаем защищенное соединение
Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, Порт, , , , 30, Защита);
// Формируем структуру данных (тело запроса)
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("partnerId", "001");
ПараметрыЗапроса.Вставить("status", "active");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
СтрокаТела = ЗаписьJSON.Закрыть();
// Формируем запрос
Запрос = Новый HTTPЗапрос("/v1/get-info");
Запрос.Заголовки.Вставить("Content-Type", "application/json");
Запрос.УстановитьТелоИзСтроки(СтрокаТела, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// Выполняем отправку
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
Сообщить("Запрос успешно выполнен!");
// Читаем JSON ответа
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
ДанныеОтвета = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Иначе
Сообщить("Ошибка! Код состояния: " + Ответ.КодСостояния);
Сообщить("Текст ошибки: " + Ответ.ПолучитьТелоКакСтроку());
КонецЕсли;
Исключение
Сообщить("Произошла критическая ошибка при отправке: " + ОписаниеОшибки());
КонецПопытки;
Если код по-прежнему возвращает 400, проанализируем ситуацию с помощью внешних инструментов. Самый эффективный способ — использовать программу Postman. Попробуйте выполнить запрос там. Если в Postman запрос проходит, а в 1С — нет, воспользуйтесь функцией просмотра «сырого» (Raw) запроса в обеих программах.
Сравните следующие параметры:
Часто выясняется, что сервер ожидает массив объектов [], а 1С отправляет структуру {}, или наоборот. Тщательная сверка текста JSON поможет быстро найти опечатку.
Для успешной отправки POST-запроса в 1С без ошибок 400 необходимо:
Content-Type: application/json.ЗащищенноеСоединениеOpenSSL для HTTPS-адресов.Следуя этим правилам, вы обеспечите стабильное взаимодействие и интеграцию между системами 1С или любыми внешними сервисами.