Как отправить POST запрос API с JSON из 1С 7.7

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

Реализация взаимодействия с современными веб-сервисами (API) из 1С:Предприятия 7.7 является нетривиальной задачей. Основная сложность заключается в том, что стандартные компоненты прошлых лет, такие как v7plus.dll, морально устарели: они не поддерживают современные протоколы шифрования (TLS 1.2+) и накладывают жесткие ограничения на управление заголовками и кодировками. В данной статье мы разберем, как правильно организовать отправку данных в формате JSON методом POST, используя более надежные системные объекты.

Почему v7plus.dll больше не подходит

Рассмотрим стандартную ситуацию: разработчик пытается использовать Addin.V7HttpReader для отправки данных. В ответ сервер часто возвращает ошибку 500 Internal Server Error или вовсе разрывает соединение. Проанализируем причины:

  1. Проблемы с TLS: Большинство современных API требуют протокол TLS 1.2. Старая компонента зачастую использует системные настройки по умолчанию, которые в старых версиях Windows ограничены TLS 1.0 или 1.1.
  2. Кодировка: 1С 7.7 работает в кодировке Windows-1251 (ANSI), в то время как стандартом для JSON является UTF-8. Если просто отправить строку, сервер не сможет ее распарсить.
  3. Заголовки: V7HttpReader некорректно обрабатывает специфические заголовки, такие как Content-Type: application/json, что приводит к тому, что сервер «не понимает», какой тип данных ему прислали.

Выяснив причины неудач, мы поймем, что для стабильной работы необходимо использовать системный объект MSXML2.ServerXMLHTTP или WinHttp.WinHttpRequest.5.1.

Шаг 1: Формирование JSON-строки

Так как в 1С 7.7 нет встроенных средств сериализации объектов в JSON, нам придется формировать строку вручную. Важно помнить о правильном экранировании кавычек и спецсимволов. Рассмотрим пример функции, которая собирает данные о документе в одну строку:


Функция СформироватьТекстЗапроса(Док)
    ТекстJSON = "{
    |  ""invoice_id"": """ + Док.НомерДок + """,
    |  ""date"": """ + Формат(Док.ДатаДок, "ДДММГГГГ") + """,
    |  ""total"": " + СокрЛП(Док.Итог("Сумма")) + ",
    |  ""items"": [";
    
    Док.ВыбратьСтроки();
    Пока Док.ПолучитьСтроку() = 1 Цикл
        ТекстJSON = ТекстJSON + "
        |    {
        |      ""code"": """ + СокрЛП(Док.Номенклатура.Код) + """,
        |      ""name"": """ + СтрЗаменить(СокрЛП(Док.Номенклатура.Наименование), """", "'") + """,
        |      ""qty"": " + СокрЛП(Док.Количество) + "
        |    },";
    КонецЦикла;
    
    // Удаляем последнюю запятую и закрываем скобки
    ТекстJSON = Лев(ТекстJSON, СтрДлина(ТекстJSON) - 1) + "
    |  ]
    |}";
    
    Возврат ТекстJSON;
КонецФункции

Важный момент: Обратите внимание на использование СтрЗаменить для наименований. Если в названии товара попадется двойная кавычка, JSON станет невалидным, и сервер выдаст ошибку 400 или 500.

Шаг 2: Конвертация данных в UTF-8

Поскольку 1С 7.7 хранит строки в кодировке Windows-1251, перед отправкой их нужно перекодировать в UTF-8. Самый надежный способ сделать это без использования внешних ВК — объект ADODB.Stream. Разберем алгоритм: мы записываем текст в поток в одной кодировке и считываем его (или сохраняем в файл) в другой.


Процедура ЗаписатьВUTF8(ТекстДляЗаписи, ИмяФайла)
    Стрим = СоздатьОбъект("ADODB.Stream");
    Стрим.Type = 2; // Text
    Стрим.Charset = "windows-1251";
    Стрим.Open();
    Стрим.WriteText(ТекстДляЗаписи);
    
    // Перематываем и меняем кодировку для сохранения
    Стрим.Position = 0;
    Стрим.Charset = "utf-8";
    
    // Сохраняем во временный файл
    Стрим.SaveToFile(ИмяФайла, 2); 
    Стрим.Close();
КонецПроцедуры

Для прямой передачи данных в запрос без промежуточного файла можно использовать свойство Type = 1 (Binary), чтобы получить массив байтов, который корректно воспримет объект HTTP-запроса.

Шаг 3: Отправка запроса через MSXML2.ServerXMLHTTP

Теперь перейдем к самому процессу отправки. Мы будем использовать MSXML2.ServerXMLHTTP.6.0. Он более стабилен в многопоточной среде и на серверных ОС, чем обычный XMLHTTP.


Функция ОтправитьЗапросНаСервер(URL, ТекстJSON)
    Попытка
        xmlHtp = СоздатьОбъект("MSXML2.ServerXMLHTTP.6.0");
        xmlHtp.Open("POST", URL, 0); // 0 - синхронный запрос
        
        // Устанавливаем критически важные заголовки
        xmlHtp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        xmlHtp.setRequestHeader("Accept", "application/json");
        
        // Отправляем данные
        xmlHtp.Send(ТекстJSON);
        
        Статус = xmlHtp.Status; // Например, 200 (ОК) или 201 (Created)
        ОтветСервера = xmlHtp.ResponseText;
        
        Сообщить("Статус ответа: " + Статус);
        Возврат ОтветСервера;
        
    Исключение
        Сообщить("Ошибка соединения: " + ОписаниеОшибки(), "!!!");
        Возврат "";
    КонецПопытки;
КонецФункции

Анализ ситуации с ошибкой 500

Если при использовании вышеуказанного кода вы все равно получаете 500 Internal Server Error, проанализируем возможные причины:

Проверить правильность вашего запроса можно, сохранив сформированный JSON в файл и отправив его через утилиту Postman. Если Postman выдает ту же ошибку — проблема в структуре JSON. Если в Postman запрос проходит — проблема в передаче заголовков или кодировке из 1С.

Дополнительные рекомендации по TLS 1.2

В операционных системах типа Windows Server 2008 R2 или Windows 7 поддержка TLS 1.2 может быть отключена на уровне системы для WinHTTP компонентов. Если вы столкнулись с ошибкой «The connection with the server was terminated abnormally», выполните следующие шаги:

  1. Установите обновления системы (KB3140245).
  2. В реестре по адресу HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp создайте параметр DefaultSecureProtocols (DWORD) со значением 0x00000800.

Это принудительно заставит системные компоненты использовать TLS 1.2, что позволит 1С 7.7 успешно подключаться к защищенным API-шлюзам (таким как у «Эпицентра», «Новой Почты» и других современных площадок).

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

← На главную