При интеграции 1С с внешними веб-сервисами разработчики часто сталкиваются с ситуацией, когда стандартная передача параметров через строку запроса (URL) не работает. Особенно это актуально для метода POST, где сервер ожидает данные внутри тела сообщения. Ошибка 401 Unauthorized или игнорирование переданных данных — типичные признаки того, что параметры переданы не по протоколу. В этой статье мы подробно разберем, как правильно формировать тело POST-запроса, настраивать заголовки и обрабатывать данные.
Рассмотрим ситуацию: нам необходимо обновить данные о сделке через API. Техническое задание требует передать userId, auth (хеш SHA-512) и dealId. Первой интуитивной попыткой часто становится добавление параметров прямо в адрес, как это делается в GET-запросах.
Проанализируем типичную ошибку в коде:
Адрес = "deals/api/sync/deal/update?auth="+auth_ХЭШI512+"&userId="+userId+"&dealId="+НомерЗаказа;
HTTPЗапрос = Новый HTTPЗапрос(Адрес, HTTPЗаголовки);
Ответ = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
В данном случае, несмотря на использование метода POST, параметры отправляются в заголовке запроса. Многие современные API блокируют такие запросы в целях безопасности или просто "не видят" эти данные, возвращая ошибку 401. Сервер ожидает, что параметры будут находиться в Body (тело) запроса.
Для того чтобы передать данные правильно, нам необходимо оставить в объекте HTTPЗапрос только путь к ресурсу, а все параметры поместить в тело. Разберем по шагам, как это реализовать.
Сначала мы формируем строку параметров в формате ключ1=значение1&ключ2=значение2. Затем используем метод УстановитьТелоИзСтроки. Посмотрим на итоговый корректный пример кода:
// Формируем путь без параметров
ПутьКРесурсу = "/deals/api/sync/deal/update";
Запрос = Новый HTTPЗапрос(ПутьКРесурсу, Заголовки);
// Формируем строку тела запроса
СтрокаПараметров = "auth=" + auth_ХЭШI512 + "&userId=" + userId + "&dealId=" + СокрЛП(Формат(НомерЗаказаНаСайте, "ЧГ="));
// Устанавливаем тело запроса
Запрос.УстановитьТелоИзСтроки(СтрокаПараметров, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// Отправляем запрос
Ответ = HTTPСоединение.ОтправитьДляОбработки(Запрос);
Проанализируем критически важный аспект, который часто упускается: сервер должен знать, как интерпретировать полученные байты данных. Если мы передаем параметры в формате строки (как в примере выше), мы обязаны указать заголовок Content-Type.
Для передачи параметров в формате "ключ-значение" используется тип application/x-www-form-urlencoded. Выясним, как добавить его в наше соответствие заголовков:
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
// Теперь сервер поймет, что тело запроса — это набор параметров
Без этого заголовка сервер может проигнорировать тело запроса, даже если оно сформировано верно.
Посмотрим на ситуацию, когда в значениях параметров могут встретиться спецсимволы: пробелы, знаки &, = или кириллица. Если вставить их "как есть", структура запроса нарушится. Рассмотрим, как применить функцию КодироватьСтроку для безопасной передачи данных.
Правильный подход к сборке строки параметров выглядит так:
ЗначениеПараметра = "Текст с пробелами и & символами";
БезопасноеЗначение = КодироватьСтроку(ЗначениеПараметра, СпособКодированияСтроки.КодировкаURL);
СтрокаПараметров = "param=" + БезопасноеЗначение;
Это гарантирует, что, например, пробел превратится в %20, и сервер корректно расшифрует данные.
В требованиях к API часто фигурирует подпись запроса с помощью хеш-функций. Выясним, как реализовать sha512, упомянутый в условии задачи. В современных версиях платформы 1С (начиная с 8.3.10) для этого предназначен объект ХешированиеДанных.
Пример получения хеша:
ХешОбъект = Новый ХешированиеДанных(ХешФункция.SHA512);
ХешОбъект.Добавить(КлючПродавца);
auth_ХЭШI512 = НРег(СтрЗаменить(Строка(ХешОбъект.ХешСумма), " ", ""));
Обратите внимание, что результат хеширования часто требуется передавать в нижнем регистре без пробелов, для чего мы используем функции НРег и СтрЗаменить.
Даже если мы выполнили все шаги правильно, важно проанализировать ответ сервера. Код состояния 401 однозначно указывает на проблемы с авторизацией (неверный хеш или ID), но другие коды (например, 400 или 500) могут сигнализировать об ошибках в структуре тела.
Разберем, как извлечь подробности ошибки:
Ответ.КодСостояния.Ответ.ПолучитьТелоКакСтроку() для анализа текста ошибки.Пример обработки ответа:
Если Ответ.КодСостояния <> 200 Тогда
Сообщить("Ошибка запроса! Код: " + Ответ.КодСостояния);
Сообщить("Детали: " + Ответ.ПолучитьТелоКакСтроку());
Иначе
// Обработка успешного результата
КонецЕсли;
Завершая разбор, проанализируем параметры самого соединения. Поскольку мы работаем с https, обязательным является использование объекта ЗащищенноеСоединениеOpenSSL. Также рекомендуется устанавливать таймаут соединения, чтобы избежать бесконечного ожидания ответа от сервера.
Защита = Новый ЗащищенноеСоединениеOpenSSL();
// Указываем таймаут 30 секунд в седьмом параметре
HTTPСоединение = Новый HTTPСоединение("api.server.com",,,,, 30, Защита);
Соблюдение этих правил позволит создать надежный механизм интеграции 1С с любыми внешними API, использующими метод POST для передачи данных.