Как правильно реализовать POST-запрос в 1С и обработать ошибку 307 Temporary Redirect при интеграции с API

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними веб-сервисами (например, платежными системами, CRM или сервисами рассылок типа JustClick) программисты часто сталкиваются с ситуацией, когда запрос идеально работает в Postman, но возвращает ошибки или пустые данные при выполнении из кода 1С. В данной статье мы подробно разберем, как правильно подготовить POST-запрос, почему стандартные методы могут не срабатывать и как обрабатывать специфические ответы сервера, такие как перенаправление 307.

Постановка задачи и анализ первичных ошибок

Рассмотрим ситуацию: необходимо отправить данные для создания заказа во внешнюю систему. Сервис ожидает POST-запрос с тремя параметрами: ключ API, email клиента и наименование продукта. Типичная ошибка начинающего разработчика — попытка передать в метод УстановитьТелоИзСтроки объект Структура напрямую или передача JSON-данных там, где сервер ожидает формат application/x-www-form-urlencoded.

Проанализируем типичный некорректный ответ сервера: "Customer email cannot be empty". Это происходит потому, что сервер не смог распознать структуру переданных данных и «увидел» пустое тело запроса. Чтобы этого избежать, нам необходимо строго соблюдать формат передачи данных и кодировку.

Шаг 1. Настройка HTTP-соединения и заголовков

Первым делом создадим объект HTTPСоединение. Обратите внимание, что для работы с защищенными ресурсами (https) необходимо использовать объект ЗащищенноеСоединениеOpenSSL. Разберем код настройки:


// Настройка защищенного соединения
Защита = Новый ЗащищенноеСоединениеOpenSSL();
// Создаем соединение с сервером
HTTPСоединение = Новый HTTPСоединение("uchi.justclick.ru", 443, , , , , Защита);

// Подготавливаем запрос к конкретному методу API
HTTPЗапрос = Новый HTTPЗапрос("/api/createorder");

// Устанавливаем обязательный заголовок для передачи параметров формы
HTTPЗапрос.Заголовки.Вставить("Content-type", "application/x-www-form-urlencoded");
HTTPЗапрос.Заголовки.Вставить("Accept-Charset", "utf-8");

Важный момент: использование заголовка Content-type: application/x-www-form-urlencoded сообщает серверу, что данные в теле запроса будут переданы в виде строки параметр1=значение1&параметр2=значение2.

Шаг 2. Правильное формирование тела запроса (URL Encoding)

Просто соединить строки через символ & недостаточно. Если в email содержится символ @, а в названии продукта — пробелы или кириллица, сервер может неправильно интерпретировать строку. Для этого в 1С используется функция КодироватьСтроку. Рассмотрим правильный способ сборки параметров:


Функция КодироватьСтрокуПараметра(Параметр, Значение)
    // Преобразуем спецсимволы в формат, понятный URL (например, @ в %40)
    Возврат КодироватьСтроку(Параметр, СпособКодированияСтроки.КодировкаURL) 
            + "=" + 
            КодироватьСтроку(Значение, СпособКодированияСтроки.КодировкаURL);
КонецФункции

// Сборка общей строки параметров
СтрокаПараметров = КодироватьСтрокуПараметра("rpsKey", КлючApi) + "&" + 
                   КодироватьСтрокуПараметра("customer_email", "test@mail.ru") + "&" + 
                   КодироватьСтрокуПараметра("product_names", "BP1C");

// Установка тела запроса без использования BOM (Byte Order Mark)
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаПараметров, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Использование ИспользованиеByteOrderMark.НеИспользовать критично, так как многие веб-серверы не понимают префикс BOM в начале строки и выдают ошибку синтаксиса.

Шаг 3. Обработка ответа и редиректа 307

Иногда после отправки корректного запроса сервер возвращает код состояния 307 (Temporary Redirect). В отличие от браузеров или Postman, объект HTTPСоединение в 1С не переходит по ссылке автоматически. Это означает, что нам нужно программно прочитать адрес перенаправления из заголовка Location и отправить запрос повторно.

Выясним причину: код 307 означает, что ресурс временно перемещен, но метод запроса (POST) должен остаться неизменным при переходе. Проанализируем ситуацию на примере кода:


// Отправляем первый запрос
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);

// Проверяем, не требует ли сервер перенаправления
Если HTTPОтвет.КодСостояния = 307 Тогда
    // Получаем новый адрес из заголовка Location
    НовыйАдрес = HTTPОтвет.Заголовки.Получить("Location");
    
    Если ЗначениеЗаполнено(НовыйАдрес) Тогда
        // Создаем новый запрос по новому адресу
        // Если адрес в Location полный (с http), нужно будет пересоздать соединение,
        // если относительный (как в нашем случае), используем текущее.
        HTTPЗапросРегирект = Новый HTTPЗапрос(НовыйАдрес);
        
        // Копируем заголовки и тело из исходного запроса
        HTTPЗапросРегирект.Заголовки.Вставить("Content-type", "application/x-www-form-urlencoded");
        HTTPЗапросРегирект.УстановитьТелоИзСтроки(СтрокаПараметров, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
        
        // Повторная отправка
        HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапросРегирект);
    КонецЕсли;
КонецЕсли;

// Проверяем итоговый результат
Если HTTPОтвет.КодСостояния = 200 Тогда
    Сообщить("Заказ успешно создан: " + HTTPОтвет.ПолучитьТелоКакСтроку());
Иначе
    Сообщить("Ошибка API: " + HTTPОтвет.ПолучитьТелоКакСтроку());
КонецЕсли;

Почему не стоит использовать JSON, если API требует Form-Data

В процессе отладки часто возникает соблазн переключиться на application/json, так как с ним удобнее работать в 1С через ЗаписьJSON. Однако, если документация API (или структура ответа, полученная ранее) явно указывает на ошибки заполнения полей при использовании x-www-form-urlencoded, значит сервер ожидает именно этот формат. Отправка JSON-строки на сервер, настроенный на прием параметров формы, приведет к ошибке "No transmitted data", так как сервер будет искать ключи в массиве $_POST (в случае PHP), а JSON прилетает в потоке php://input.

Резюме и рекомендации

Для стабильной работы интеграций через HTTP-запросы в 1С рекомендуем придерживаться следующих правил:

  1. Всегда кодируйте значения параметров
  2. через КодироватьСтроку со способом КодировкаURL.
  3. Контролируйте заголовки
  4. . Убедитесь, что Content-type соответствует ожиданиям сервера (чаще всего это application/x-www-form-urlencoded или application/json).
  5. Обрабатывайте статус-коды вручную
  6. . Не ограничивайтесь проверкой только на код 200. Логика обработки 301, 302 и 307 должна быть заложена в архитектуру вашего обмена.
  7. Используйте отладку
  8. . Метод HTTPОтвет.ПолучитьТелоКакСтроку() — ваш главный инструмент для понимания того, почему внешняя система отклонила запрос.

Рассмотренный подход позволяет обходить ограничения автоматических систем перенаправления и гарантирует доставку данных даже в тех случаях, когда API сервиса выполняет внутреннюю маршрутизацию запросов между своими серверами.

← На главную