Как правильно выполнить POST-запрос из 1С к внешнему API с передачей параметров в формате application/x-www-form-urlencoded?

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

Интеграция 1С с внешними веб-сервисами часто сопровождается трудностями, особенно когда API ожидает данные в специфическом формате. Одной из самых распространенных проблем является несоответствие заголовков запроса и структуры передаваемого тела данных. Часто разработчики пытаются отправить данные в формате JSON, в то время как сервер ожидает стандартную форму (как при отправке данных из веб-браузера). В этой статье мы разберем по шагам, как настроить HTTPЗапрос, чтобы он успешно прошел проверку на стороне сервера.

Анализируем исходную задачу и типичные ошибки

Рассмотрим ситуацию: у нас есть рабочий пример вызова через утилиту curl, который предоставил разработчик сайта:

curl -d "_token=123456" -X POST http://sanstore.crm.instaboss.kz/api/add-clients

Проанализируем этот вызов. Флаг -d (data) в curl по умолчанию делает две важные вещи:

  1. Устанавливает метод запроса в POST.
  2. Автоматически добавляет заголовок Content-Type: application/x-www-form-urlencoded.

В начальном коде в 1С была допущена ошибка — попытка собрать тело запроса через ЗаписьJSON. Большинство современных API действительно работают с JSON, но если сервер настроен на прием «форм», JSON-структура приведет к ошибке 500 (Internal Server Error), так как сервер не сможет корректно разобрать входящий поток данных.

Разбор ошибок с кодами состояния 302 и 500

В процессе отладки автор столкнулся с двумя типами ответов сервера:

Пошаговое решение проблемы

Чтобы успешно выполнить запрос, нам необходимо привести код 1С в полное соответствие с логикой работы curl. Разберем правильный алгоритм работы.

Шаг 1: Подготовка заголовков. Нам нужно явно указать серверу, что мы передаем данные в формате формы. Для этого используется объект Соответствие.


Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded"); 

Шаг 2: Формирование тела запроса. Вместо использования ЗаписьJSON, мы подготавливаем обычную строку, где параметры разделены символом & (если их несколько). Важно помнить про кодирование спецсимволов.


// Формируем строку параметров
СтрокаТела = "_token=" + "123456";
// Если параметров несколько:
// СтрокаТела = "_token=" + Токен + "&client_id=" + ID;

Шаг 3: Настройка соединения и отправка. При создании HTTPСоединение важно правильно указать хост и порт. Если сайт работает через защищенное соединение, необходимо добавить объект ЗащищенноеСоединениеOpenSSL.

Итоговый рабочий пример кода

Проанализируем финальный вариант кода, который позволил успешно интегрировать 1С с API:


// 1. Создаем соответствие для заголовков
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded"); 

// 2. Настраиваем соединение с сервером
// Обратите внимание: указываем только доменное имя, без префиксов http/https
Сервер = "sanstore.crm.instaboss.kz";
Соединение = Новый HTTPСоединение(Сервер, 80); // Или 443 с использованием ЗащищенноеСоединениеOpenSSL

// 3. Создаем объект запроса с указанием относительного пути и заголовков
ПутьКРесурсу = "api/add-clients";
HTTPЗапрос = Новый HTTPЗапрос(ПутьКРесурсу, Заголовки);

// 4. Устанавливаем тело запроса
// Важно: в POST запросах данные передаются в теле, а не в URL
СтрокаПараметров = "_token=123456";
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаПараметров, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

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

Важные нюансы и рекомендации

Рассмотрим несколько дополнительных моментов, которые помогут сделать ваше решение более надежным:

  1. URL-кодирование: Если значения ваших параметров могут содержать пробелы, кириллицу или спецсимволы (например, & или +), их обязательно нужно кодировать. Используйте функцию КодироватьСтроку(Значение, СпособКодированияСтроки.КодировкаURL).
  2. Использование HTTPS: Большинство современных CRM-систем (включая системы на базе Laravel, как в примере) требуют защищенного соединения. Если вы получаете ошибку 302, попробуйте изменить порт на 443 и добавить параметры безопасности:
    
    Соединение = Новый HTTPСоединение(Сервер, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
    
  3. Диагностика через Postman: Если запрос не проходит, воспользуйтесь программой Postman. Она позволяет визуально настроить параметры и заголовки, а затем автоматически генерирует код на разных языках программирования. Сравнение заголовков, которые отправляет Postman, с заголовками в 1С — самый быстрый способ найти ошибку.
  4. Чтение тела ответа при ошибке 500: Даже если сервер вернул ошибку 500, он часто присылает детальное описание проблемы в формате JSON. Всегда считывайте тело ответа через Результат.ПолучитьТелоИзСтроки(), чтобы понять, какой именно параметр не нравится серверу.

Таким образом, успех интеграции 1С с внешними API напрямую зависит от точного соблюдения протокола передачи данных. Установка правильного Content-Type и корректная передача параметров в теле запроса — это фундамент стабильной работы обмена данными.

← На главную