Как переписать PHP-скрипт cURL для отправки HTTP POST-запроса на языке 1С

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

При интеграции 1С:Предприятие со сторонними веб-сервисами и API разработчики часто сталкиваются с ситуацией, когда готовый пример взаимодействия предоставлен только в виде PHP-скрипта с использованием библиотеки cURL. Задача перевода такого кода на язык 1С требует понимания того, как сопоставлять опции cURL с объектами платформ 1С (такими как HTTPСоединение и HTTPЗапрос), а также знания нюансов кодирования данных, работы с SSL и обработки HTTP-заголовков.

В данной статье мы подробно разберем, как корректно перенести отправку POST-запроса из PHP cURL в 1С:Предприятие 8.3, рассмотрим особенности формирования тела запроса, работу с защищенными соединениями HTTPS и альтернативные способы через COM-объекты.

1. Анализ исходного PHP-скрипта и сопоставление с объектами 1С

Проанализируем исходный PHP-код, предоставленный в качестве примера взаимодействия:


<?php 
getTyres();
function getTyres(){
    $ch = curl_init();
    $data = array(
        'secret' => 'ключ',     
        'id' => 'ИД', 
    ); 
    curl_setopt($ch, CURLOPT_URL, 'https://сайт/parcelsApi/track'); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_POSTREDIR, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, '3600');
    $content = trim(curl_exec($ch));
    curl_close($ch);
    
    var_dump($content); 
}

Сопоставим ключевые параметры cURL с механизмами платформы 1С:

  1. Параметры подключения и URL: В 1С имя сервера (хост) и путь к ресурсу разделяются. Хост (например, сайт) передается в конструктор объекта HTTPСоединение, а адрес ресурса (/parcelsApi/track) — в объект HTTPЗапрос.
  2. Передача данных (CURLOPT_POSTFIELDS): В PHP передача массива приводит к автоматическому формированию тела запроса. В 1С необходимо самостоятельно сформировать строку параметров формата application/x-www-form-urlencoded или структуру JSON и закодировать значения с помощью функции КодироватьCтроку.
  3. Таймаут (CURLOPT_TIMEOUT): Указывается при инициализации объекта HTTPСоединение в секундах.
  4. Защищенное соединение (HTTPS): Для работы по протоколу HTTPS в 1С создается объект ЗащищенноеСоединениеOpenSSL.

2. Реализация POST-запроса средствами 1С (HTTPСоединение и HTTPЗапрос)

Рассмотрим по шагам создание функции на языке 1С, выполняющей аналогичный POST-запрос на сервере платформы 1С 8.3.

Сформируем полный рабочий пример кода:


Функция ПолучитьДанныеПоШинам()

    // 1. Разделяем адрес на сервер и путь к ресурсу
    Сервер = "сайт"; // Указывается доменное имя без "https://"
    АдресРесурса = "/parcelsApi/track";

    // 2. Формируем заголовки HTTP-запроса
    Заголовки = Новый Соответствие();
    Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");

    // 3. Подготавливаем параметры и кодируем их для URL
    ЗначениеСекрет = КодироватьCтроку("ваш_ключ", СпособКодированияСтроки.URLКодирование);
    ЗначениеИД     = КодироватьCтроку("ваш_ид", СпособКодированияСтроки.URLКодирование);

    ТелоЗапроса = СтрШаблон("secret=%1&id=%2", ЗначениеСекрет, ЗначениеИД);

    // 4. Настраиваем SSL-соединение для работы по HTTPS
    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();

    // 5. Создаем HTTPСоединение (хост, порт 443 для HTTPS, таймаут 3600 сек)
    Таймаут = 3600;
    Соединение = Новый HTTPСоединение(Сервер, 443, , , , Таймаут, ЗащищенноеСоединение);

    // 6. Формируем HTTPЗапрос
    Запрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
    Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

    Попытка
        // Отправляем POST-запрос методом ОтправитьДляОбработки
        Ответ = Соединение.ОтправитьДляОбработки(Запрос);
        
        КодСостояния = Ответ.КодСостояния;
        ТекстОтвета  = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
        
        Если КодСостояния = 200 Тогда
            // Декодируем полученный JSON-ответ
            Чтение = Новый ЧтениеJSON;
            Чтение.УстановитьСтроку(ТекстОтвета);
            Данные = ПрочитатьJSON(Чтение);
            Чтение.Закрыть();
            
            Возврат Данные;
        Иначе
            ЗаписьЖурналаРегистрации("Ошибка API", УровеньЖурналаРегистрации.Ошибка,,, 
                СтрШаблон("Код ошибки: %1. Ответ: %2", КодСостояния, ТекстОтвета));
            Возврат Неопределено;
        КонецЕсли;
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка Подключения API", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
        ВызватьИсключение;
    КонецПопытки;

КонецФункции

3. Альтернативный вариант: Использование COM-объекта WinHttp.WinHttpRequest.5.1

В некоторых сценариях, когда код выполняется исключительно на сервере под управлением операционной системы Windows, удобно использовать COM-объект WinHttp.WinHttpRequest.5.1. Он автоматически обрабатывает системные сертификаты Windows и поддерживает перенаправления без написания дополнительной логики.

Разберем пример реализации через COM-объект:


Функция ВыполнитьЗапросЧерезCOM()

    Попытка
        WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка COM", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;

    // Настройка параметров WinHttp
    // Option(6) = EnableRedirects (аналог CURLOPT_FOLLOWLOCATION в cURL)
    WinHttp.Option(6, 1);

    // Установка таймаутов (в миллисекундах): Resolve, Connect, Send, Receive
    WinHttp.Timeouts(30000, 30000, 3600000, 3600000);

    URL = "https://сайт/parcelsApi/track";
    WinHttp.Open("POST", URL, Ложь); // Ложь = синхронный вызов

    // Устанавливаем заголовок Content-Type
    WinHttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

    // Формируем параметры запроса
    Секрет = КодироватьCтроку("ваш_ключ", СпособКодированияСтроки.URLКодирование);
    ИД     = КодироватьCтроку("ваш_ид", СпособКодированияСтроки.URLКодирование);
    ТелоЗапроса = "secret=" + Секрет + "&id=" + ИД;

    // Отправка запроса
    WinHttp.Send(ТелоЗапроса);

    КодСостояния = WinHttp.Status;
    ТекстОтвета  = WinHttp.ResponseText;

    Если КодСостояния = 200 Тогда
        Возврат ТекстОтвета;
    Иначе
        ЗаписьЖурналаРегистрации("Ошибка WinHttp", УровеньЖурналаРегистрации.Ошибка,,,
            СтрШаблон("Код: %1, Ответ: %2", КодСостояния, ТекстОтвета));
        Возврат Неопределено;
    КонецЕсли;

КонецФункции

Важно: Вариант с COM-объектом подходит только для системы Windows. Если сервер 1С работает под управлением Linux, следует использовать исключительно встроенные объекты HTTPСоединение и HTTPЗапрос.

4. Распространенные проблемы и подводные камни

Рассмотрев оба варианта реализации, выясним, почему при переносе кода с PHP на 1С часто возникают ошибки вида {"error":"Unknown user"} или 400 Bad Request.

  1. Отличия в обработке массива в CURLOPT_POSTFIELDS: В PHP передача массива в curl_setopt($ch, CURLOPT_POSTFIELDS, $array) приводит к автоматической генерации запроса вида multipart/form-data. Если же в PHP передается предварительно собранная строка http_build_query($array), отправляется тип application/x-www-form-urlencoded. В 1С тип содержимого фиксируется явно в заголовке Content-Type, поэтому важно указывать именно тот формат, который ожидает сервер.
  2. Кодирование спецсимволов и кириллицы: При передаче ключей и идентификаторов, содержащих специальные символы (=, &, пробелы) или кириллицу, обязательна их обработка функцией КодироватьCтроку(..., СпособКодированияСтроки.URLКодирование). Без кодирования сервер не сможет правильно разобрать параметры запроса.
  3. Перенаправления (HTTP Redirects 301/302): Параметр CURLOPT_FOLLOWLOCATION = true в PHP заставляет cURL автоматически следовать по редиректам. В 1С объект HTTPСоединение при отправке POST-запроса может вернуть код 301 или 302. В таком случае необходимо извлечь из заголовков ответа заголовок Location и отправить повторный запрос по новому адресу.
  4. Опечатки в параметрах авторизации: Как показывает практика, самой частой причиной ответа {"error":"Unknown user"} являются банальные опечатки в наименованиях полей (например, secret вместо key) или значениях идентификаторов, допущенные при ручном переносе кода.

5. Рекомендации по отладке сетевых запросов

Если запрос из 1С не получает ожидаемый ответ от сервера, рекомендуем использовать следующие инструменты и методы отладки:

  1. Сравнение сетевых дампов (Сниффер трафика): С помощью утилит, таких как Fiddler или Wireshark, перехватите сырой HTTP-запрос, отправляемый PHP-скриптом, и аналогичный запрос из 1С. Сравните заголовки, кодировку и структуру тела запроса.
  2. Тестирование через Postman: Создайте аналогичный POST-запрос в утилите Postman. Убедитесь в корректности работы API и затем перенесите точный набор заголовков и параметров в код 1С.
  3. Логирование в Журнал регистрации: Всегда оборачивайте сетевые вызовы в блок Попытка ... Исключение и фиксируйте полученный код состояния и текст ответа в ЖурналРегистрации. Это существенно упростит поиск причин ошибок на продуктовых серверах.
← На главную