Как отправить POST-запрос с телом JSON из 1С в amoCRM и избежать ошибок 301 и 400?

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

При разработке интеграций между 1С и внешними веб-сервисами разработчики часто сталкиваются с нестандартным поведением HTTP-клиента. Типичная задача — выгрузка контактных данных или контрагентов из 1С во внешнюю CRM-систему (например, amoCRM) через REST API с передачей данных в формате JSON. Однако в процессе отправки запроса сервер может возвращать коды состояния 301 Moved Permanently или 400 Bad Request. Разберем по шагам, почему возникают эти ошибки и как правильно реализовать отправку данных средствами платформы 1С:Предприятие.

Анализ причин возникновения ошибок 301 и 400

Выясним причину, по которой веб-сервер возвращает подобные статусы ответов:

  1. Ошибка 301 Moved Permanently (Перемещено навсегда). Возникает, если инициализировать объект HTTPСоединение без указания защищенного протокола, отправляя запрос по стандартному порту 80 (HTTP). Большинство современных облачных сервисов работают исключительно по протоколу HTTPS (порт 443). При попытке обратиться по незащищенному протоколу сервер выполняет принудительный редирект, возвращая статус 301.
  2. Использование неподходящего HTTP-метода. Метод платформы HTTPСоединение.Получить() отправляет запрос с методом GET. Попытка передать тело запроса через GET-запрос либо некорректна для API, либо полностью игнорируется веб-сервером, что приводит к ошибкам маршрутизации или отклонению вызова. Для отправки полезной нагрузки необходимо использовать метод POST (в 1С это метод ОтправитьДляОбработки).
  3. Некорректная ручная установка заголовков. Одной из главных причин ошибки 400 Bad Request является попытка вручную прописать служебные HTTP-заголовки. Например, если принудительно задать заголовок Content-Length: 1 при фактическом размере тела в несколько сотен байт, веб-сервер прочитает только первый байт и признает синтаксис запроса поврежденным. Платформа 1С умеет автоматически рассчитывать размер передаваемого тела и корректно заполнять заголовки Host и Content-Length.

Пошаговое построение корректного HTTP POST-запроса

Разберем последовательность действий, необходимых для надежной отправки структуры JSON на удаленный сервер.

  1. Инициализация защищенного подключения. Создаем экземпляр ЗащищенноеСоединениеOpenSSL и передаем его в конструктор HTTPСоединение, указав имя хоста без протоколов (без префикса «https://»).
  2. Подготовка объекта запроса. Создаем объект HTTPЗапрос, указав в качестве параметра относительный URI ресурса вместе со строкой параметров запроса.
  3. Заполнение заголовков запроса. Для передачи данных в формате JSON сервер ожидает явного указания типа содержимого в заголовке Content-Type: application/json; charset=utf-8. Служебные заголовки Host и Content-Length вручную устанавливать не следует.
  4. Установка тела запроса. Передаем подготовленную строку JSON в тело запроса с помощью метода УстановитьТелоИзСтроки(), обязательно отключив маркер последовательности байтов (BOM), который может вызвать сбой синтаксического анализа на стороне сервера.
  5. Отправка и обработка ответа. Вызываем метод ОтправитьДляОбработки(). Результат можно сразу получить в виде объекта HTTPОтвет без создания лишних временных файлов на диске.

Рабочий пример отправки запроса

Рассмотрим рабочий вариант кода, который решает проблему установки защищенного соединения и успешной передачи JSON в тело запроса:


// 1. Читаем данные JSON из файла или формируем программно
Текст = Новый ЧтениеТекста("C:\Users\User\Desktop\amo crm\jsonПример.txt", КодировкаТекста.UTF8);
СтрокаJSON = Текст.Прочитать();
Текст.Закрыть();

// 2. Инициализируем защищенное HTTPS-соединение
Сервер = "new590c1f3d3ac3b.amocrm.ru";
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение(Сервер, 443,,,,, ЗащищенноеСоединение, Истина);

// 3. Формируем путь ресурса и сам запрос
ПутьРесурса = "/private/api/v2/json/contacts/set?USER_HASH=0e2bdd0bae2807a29efacf0c6535166a&USER_LOGIN=zapolski.slava@gmail.com";
HTTPЗапрос = Новый HTTPЗапрос(ПутьРесурса);

// 4. Задаем корректные заголовки и тело
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

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

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

Рекомендации по оптимизации интеграции и надежности

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

  1. Формирование JSON штатными средствами. Ручная конкатенация строк или чтение сырого текста из файлов чреваты нарушением синтаксиса (например, при наличии кавычек или переносов строк в наименованиях контрагентов). Рекомендуется использовать встроенные объекты платформы ЗаписьJSON и процедуру ЗаписатьJSON, передавая в них структуры и массивы 1С.
  2. Работа без промежуточных файлов. Метод HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос) возвращает объект HTTPОтвет. Нет необходимости использовать ПолучитьИмяВременногоФайла() для сохранения ответа на диск и последующего его чтения — это снижает нагрузку на дисковую подсистему и ускоряет работу обмена.
  3. Ограничения внешнего API на частоту запросов. Сервисы amoCRM накладывают строгие лимиты (не более 7 запросов в секунду на аккаунт). При превышении лимита возвращается ошибка 429 Too Many Requests. При массовой выгрузке контрагентов необходимо группировать данные в пакеты (массивы) в одном запросе или реализовывать паузы между отправками.
  4. Актуальность версий протоколов авторизации. Передача авторизационных данных через параметры строки запроса (USER_LOGIN и USER_HASH) устарела. В актуальных версиях API amoCRM (REST API v4) применяется протокол OAuth 2.0, где ключ доступа передается в заголовке Authorization: Bearer <токен>, а в 1С настраивается периодическое обновление access_token с помощью refresh_token.
← На главную