При разработке интеграций между устаревшими конфигурациями на платформе 1С:Предприятие 7.7 и современными CRM-системами (например, amoCRM, Bitrix24 и др.) разработчики часто сталкиваются с трудностями. Большинство современных веб-сервисов предоставляют примеры запросов в формате утилиты cURL. Попытка перенести эти примеры «как есть» в код 1С приводит к синтаксическим ошибкам и отказам со стороны сервера.
В этой статье мы подробно разберем, как правильно перевести cURL-запрос в формат объекта WinHttp.WinHttpRequest.5.1, настроить авторизацию, обойти ограничения кодировок в 1С 7.7, активировать поддержку протоколов TLS 1.2 и научиться разбирать полученные JSON-ответы без использования сторонних внешних компонент.
Частой ошибкой при переносе параметров из документации API является копирование служебных символов командной строки cURL. Рассмотрим пример некорректного тела запроса, с которым столкнулся автор темы:
Параметры = "@- << EOF {""data"":{""type"":""deal-stages""...}}EOF"
Конструкции @- << EOF и завершающее EOF — это команды интерпретатора Bash (разновидность «Here-Document»), которые указывают cURL принять текст внутри блока как тело запроса. При отправке запроса из 1С эти служебные символы попадают непосредственно в тело HTTP-пакета. Веб-сервер пытается распарсить их как JSON и возвращает ошибку Bad Request (400).
Решение: Передавать нужно исключительно «чистую» строку JSON. Уберем все лишнее:
Параметры = "{""data"":{""type"":""deal-stages"",""attributes"":{""name"":""API 1234""},""relationships"":{""deal-stage-category"":{""data"":{""type"":""deal-stage-categories"",""id"":1}}}}";
Для доступа к большинству современных API требуется авторизация по протоколу OAuth 2.0 с использованием токенов доступа. В cURL-запросе это выглядит так: -H "Authorization: Bearer api_token".
Разработчики часто совершают ошибку, передавая только сам токен в заголовок. Для успешной авторизации необходимо обязательно добавлять префикс Bearer (с пробелом после него) перед самим ключом.
Проанализируем правильный вариант установки заголовка в 1С 7.7:
ТокенДоступа = "ваш_api_токен";
Соединение.setRequestHeader("Authorization", "Bearer " + ТокенДоступа);
Формирование длинных JSON-строк непосредственно в коде 1С 7.7 сопряжено с постоянным экранированием двойных кавычек (символы ""). Такой код крайне сложно читать и редактировать. Чтобы сделать структуру наглядной, применим изящное решение: будем использовать стандартные шаблоны таблиц 1С.
Разберем этот метод пошагово:
ЗапросыHTTP.СоздатьЭтапСделки).&ИмяЭтапа&:
{
"data": {
"type": "deal-stages",
"attributes": {
"name": "&ИмяЭтапа&"
},
"relationships": {
"deal-stage-category": {
"data": {
"type": "deal-stage-categories",
"id": 1
}
}
}
}
}
Теперь напишем функцию для извлечения шаблона и заполнения параметров в коде 1С 7.7:
Функция ПолучитьТелоЗапроса(ИмяСекции, ЗначениеПараметра)
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("ЗапросыHTTP");
Таб.ВывестиСекцию(ИмяСекции);
ШаблонJSON = Таб.Область(1, 1).Текст;
// Заменяем маркеры реальными данными
ТекстJSON = СтрЗаменить(ШаблонJSON, "&ИмяЭтапа&", ЗначениеПараметра);
Возврат ТекстJSON;
КонецФункции
Этот способ избавляет от необходимости возиться со склеиванием кавычек вида Кав = """" и делает код максимально чистым.
Платформа 1С 7.7 работает в кодировке Windows-1251 (ANSI). Любые русские символы, отправленные в этой кодировке, превратятся на веб-сервере в нечитаемые символы («кракозябры»). В то же время, ответы от веб-сервисов в кодировке UTF-8 будут отображаться в 1С некорректно.
Для надежного обмена данными преобразуем исходящие строки в UTF-8, а входящие — обратно в Windows-1251, используя системный COM-объект ADODB.Stream. Разработаем две универсальные функции:
// Преобразует строку 1С в бинарные данные UTF-8 для отправки на сервер
Функция ПреобразоватьВ_UTF8(ТекстJSON)
Стрим = СоздатьОбъект("ADODB.Stream");
Стрим.Type = 2; // Текстовый режим
Стрим.Charset = "utf-8";
Стрим.Open();
Стрим.WriteText(ТекстJSON);
// Переводим стрим в бинарный режим для передачи WinHttp
Стрим.Position = 0;
Стрим.Type = 1; // Бинарный режим
ДвоичныеДанные = Стрим.Read();
Стрим.Close();
Возврат ДвоичныеДанные;
КонецФункции
// Декодирует сырой бинарный ответ сервера из UTF-8 в Windows-1251
Функция ДекодироватьИз_UTF8(ОбъектWinHttp)
Стрим = СоздатьОбъект("ADODB.Stream");
Стрим.Type = 1; // Бинарный режим
Стрим.Open();
// Извлекаем именно ResponseBody (массив байт), а не ResponseText
Стрим.Write(ОбъектWinHttp.ResponseBody);
Стрим.Position = 0;
Стрим.Type = 2; // Переключаем в текстовый режим
Стрим.Charset = "utf-8";
ДекодированныйТекст = Стрим.ReadText();
Стрим.Close();
Возврат ДекодированныйТекст;
КонецФункции
Современные веб-серверы блокируют небезопасные протоколы SSL и устаревшие TLS 1.0/1.1. По умолчанию объект WinHttp.WinHttpRequest.5.1 в среде старых операционных систем может вызывать ошибки подключения при обращении к защищенным сайтам по протоколу HTTPS.
Для принудительного использования протокола безопасности TLS 1.2 необходимо установить специальную опцию конфигурации №9 перед отправкой запроса:
Соединение = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
Соединение.Open("POST", URL, 0);
// Принудительно задаем использование протокола TLS 1.2 (код опции 2048)
Соединение.Option(9) = 2048;
Разбирать полученную строку ответа регулярными выражениями или строковыми функциями неэффективно. Вместо этого задействуем стандартный системный скриптовый движок Windows — MSScriptControl.ScriptControl с поддержкой языка JScript, который «из коробки» умеет работать со структурами JSON:
Функция ПолучитьЗначениеИзJSON(ТекстJSON, ПутьККлючу)
Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
Скрипт.Language = "JScript";
// Добавляем JS-функции для парсинга
Скрипт.AddCode("
|function parseJSON(str) {
| return eval('(' + str + ')');
|}
|function getVal(obj, path) {
| return eval('obj.' + path);
|}
|");
Попытка
JS_Объект = Скрипт.Run("parseJSON", ТекстJSON);
Значение = Скрипт.Run("getVal", JS_Объект, ПутьККлючу);
Возврат Значение;
Исключение
Возврат "";
КонецПопытки;
КонецФункции
Теперь, если сервер присылает нам сложную структуру, например: {"data":{"id":125,"attributes":{"status":"active"}}}, мы сможем извлечь идентификатор вызовом:
Идентификатор = ПолучитьЗначениеИзJSON(ТекстОтвета, "data.id");
Соберем все описанные приемы и лучшие практики в одну общую процедуру отправки запроса к CRM-системе:
Процедура ВыполнитьЭкспортВ_CRM()
// 1. Инициализируем адрес и токен авторизации
АдресРесурса = "https://api.yourcrm.com/v1/deal-stages";
Токен = "your_secret_api_token";
// 2. Получаем шаблон JSON-тела из таблицы и подставляем имя этапа
ТекстПараметров = ПолучитьТелоЗапроса("СоздатьЭтапСделки", "Новый этап API");
// 3. Кодируем тело в UTF-8
ТелоЗапроса = ПреобразоватьВ_UTF8(ТекстПараметров);
// 4. Настраиваем WinHttp соединение
Соединение = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
Попытка
Соединение.Open("POST", АдресРесурса, 0);
// Включаем поддержку безопасного протокола TLS 1.2
Соединение.Option(9) = 2048;
// Устанавливаем заголовки
Соединение.setRequestHeader("Content-Type", "application/vnd.api+json");
Соединение.setRequestHeader("Authorization", "Bearer " + Токен);
// Отправляем бинарные данные
Соединение.Send(ТелоЗапроса);
Исключение
Предупреждение("Не удалось установить связь с сервером CRM!");
Возврат;
КонецПопытки;
// 5. Проверяем HTTP-статус ответа
КодРезультата = Соединение.Status;
ТекстРезультата = Соединение.StatusText;
Если (КодРезультата = 200) Или (КодРезультата = 201) Тогда
// Декодируем успешный ответ в Windows-1251
ОтветСервера = ДекодироватьИз_UTF8(Соединение);
// Разбираем JSON и извлекаем ID созданной записи
НовыйID = ПолучитьЗначениеИзJSON(ОтветСервера, "data.id");
Сообщить("Запрос успешно обработан. Код ответа: " + КодРезультата);
Сообщить("Созданному объекту в CRM присвоен ID: " + НовыйID);
Иначе
// Обрабатываем возникшие ошибки авторизации или структуры
ТекстОшибки = ДекодироватьИз_UTF8(Соединение);
Сообщить("Ошибка запроса! Код: " + КодРезультата + " (" + ТекстРезультата + ")", "!");
Сообщить("Подробности ошибки: " + ТекстОшибки);
КонецЕсли;
КонецПроцедуры
Использование этого комплексного подхода позволяет полностью решить проблемы интеграции 1С 7.7 с внешними веб-сервисами, сохраняя при этом гибкость разработки, производительность и высокую читаемость исходного кода.