Как настроить интеграцию 1С 7.7 с REST API и исправить ошибки при отправке JSON-запросов?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке интеграций между устаревшими конфигурациями на платформе 1С:Предприятие 7.7 и современными CRM-системами (например, amoCRM, Bitrix24 и др.) разработчики часто сталкиваются с трудностями. Большинство современных веб-сервисов предоставляют примеры запросов в формате утилиты cURL. Попытка перенести эти примеры «как есть» в код 1С приводит к синтаксическим ошибкам и отказам со стороны сервера.

В этой статье мы подробно разберем, как правильно перевести cURL-запрос в формат объекта WinHttp.WinHttpRequest.5.1, настроить авторизацию, обойти ограничения кодировок в 1С 7.7, активировать поддержку протоколов TLS 1.2 и научиться разбирать полученные JSON-ответы без использования сторонних внешних компонент.

Шаг 1. Очистка тела запроса от синтаксиса cURL

Частой ошибкой при переносе параметров из документации 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}}}}";

Шаг 2. Настройка заголовка авторизации (Bearer Token)

Для доступа к большинству современных API требуется авторизация по протоколу OAuth 2.0 с использованием токенов доступа. В cURL-запросе это выглядит так: -H "Authorization: Bearer api_token".

Разработчики часто совершают ошибку, передавая только сам токен в заголовок. Для успешной авторизации необходимо обязательно добавлять префикс Bearer (с пробелом после него) перед самим ключом.

Проанализируем правильный вариант установки заголовка в 1С 7.7:


ТокенДоступа = "ваш_api_токен";
Соединение.setRequestHeader("Authorization", "Bearer " + ТокенДоступа);

Шаг 3. Удобное формирование JSON-строки через макеты таблиц

Формирование длинных JSON-строк непосредственно в коде 1С 7.7 сопряжено с постоянным экранированием двойных кавычек (символы ""). Такой код крайне сложно читать и редактировать. Чтобы сделать структуру наглядной, применим изящное решение: будем использовать стандартные шаблоны таблиц 1С.

Разберем этот метод пошагово:

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

{
  "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;
КонецФункции

Этот способ избавляет от необходимости возиться со склеиванием кавычек вида Кав = """" и делает код максимально чистым.

Шаг 4. Решение проблемы кодировки UTF-8

Платформа 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();
    
    Возврат ДекодированныйТекст;
КонецФункции

Шаг 5. Активация протокола шифрования TLS 1.2

Современные веб-серверы блокируют небезопасные протоколы 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; 

Шаг 6. Разбор полученного JSON-ответа без внешних компонент

Разбирать полученную строку ответа регулярными выражениями или строковыми функциями неэффективно. Вместо этого задействуем стандартный системный скриптовый движок 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 с внешними веб-сервисами, сохраняя при этом гибкость разработки, производительность и высокую читаемость исходного кода.

← На главную