Как получить и сохранить PDF-файл через GET-запрос в 1С 7.7

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

При интеграции 1С:Предприятие 7.7 с современными веб-сервисами (например, СБИС ОФД для получения чеков) программисты часто сталкиваются с фундаментальным ограничением платформы: отсутствием встроенной поддержки бинарных данных (массивов байтов). В этой статье мы подробно разберем, почему стандартные методы не работают и как изящно решить задачу сохранения PDF-файла с помощью COM-объектов и скриптовых вставок.

В чем заключается основная сложность

Когда мы выполняем HTTP-запрос через объект WinHttp.WinHttpRequest.5.1 или Msxml2.ServerXMLHTTP, сервер в ответ на запрос файла возвращает поток данных. В современных версиях 1С (8.3) для этого существуют методы ПолучитьТелоКакДвоичныеДанные(), но в версии 7.7 попытка обратиться к свойству ResponseBody или ResponseStream приводит к ошибке "Тип переменной не поддерживается". Это происходит потому, что COM-объект возвращает массив типа VT_ARRAY | VT_UI1, который среда 1С 7.7 не может интерпретировать и поместить в свою переменную.

Попытки использовать ResponseText для сохранения бинарных файлов (PDF, картинки, архивы) также обречены на провал. Метод ResponseText пытается преобразовать байты в символы согласно кодировке, что необратимо повреждает структуру PDF-файла. Проанализируем правильный подход к решению этой задачи.

Шаг 1. Формирование HTTP-запроса

Сначала рассмотрим, как правильно настроить объект запроса. Для взаимодействия с API СБИС нам потребуется авторизация (обычно через Cookie) и установка соответствующих заголовков. Разберем пример кода для инициализации запроса:


ОтправЧек = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
url = "https://api.sbis.ru/ofd/v1/orgs/" + ИдОрг + "/kkts/" + ИдКкт + "/storages/docs/" + ИдДок + "?format=pdf";

ОтправЧек.open("GET", url, 0); // 0 - синхронный режим
ОтправЧек.setRequestHeader("Cookie", СИД); // Передаем идентификатор сессии
ОтправЧек.setRequestHeader("Content-Type", "application/json; charset=utf-8");
ОтправЧек.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");

ОтправЧек.send();

Здесь важно обратить внимание на заголовок User-Agent. Некоторые сервера блокируют запросы с пустым или специфическим заголовком (например, стандартным для Python или старых библиотек), поэтому лучше указывать строку, имитирующую современный браузер.

Шаг 2. Проблема сохранения данных

После выполнения метода send() мы должны проверить статус ответа. Если статус 200 (OK), файл готов к загрузке. Однако, как мы выяснили, прямой вызов ОтправЧек.ResponseBody в коде 1С вызовет ошибку. Нам нужно передать этот объект туда, где бинарные данные поддерживаются «из коробки».

Идеальным посредником выступает объект MSScriptControl.ScriptControl. Он позволяет выполнить код на языке VBScript или JScript прямо внутри сессии 1С. Эти языки корректно обрабатывают COM-массивы байтов и могут передать их в объект ADODB.Stream, который умеет записывать данные на диск.

Шаг 3. Реализация сохранения через VBScript

Рассмотрим подробнее реализацию функции сохранения. Мы создадим скрипт, который принимает объект запроса и путь к файлу, а затем выполняет сохранение. Проанализируем структуру этого скрипта:

  1. Создаем объект MSScriptControl.ScriptControl.
  2. Устанавливаем язык VBScript.
  3. Описываем процедуру, которая инициализирует ADODB.Stream.
  4. Устанавливаем тип потока Type = 1 (бинарный режим).
  5. Записываем ResponseBody в поток и сохраняем файл.

Вот как выглядит итоговый рабочий код для 1С 7.7:


Если ОтправЧек.status = 200 Тогда
    ПутьКФайлу = "C:\temp\receipt.pdf";
    
    // Инициализируем скрипт для обхода ограничений 1С по типам данных
    Scr = СоздатьОбъект("MSScriptControl.ScriptControl");
    Scr.Language = "vbscript";
    
    ТекстМодуля = "
    |Sub SaveToFile(ByRef FileName, ByRef WinHttp)
    |    Set Stream = CreateObject(""ADODB.Stream"")
    |    Stream.Type = 1 ' adTypeBinary
    |    Stream.Mode = 3 ' adModeReadWrite
    |    Stream.Open
    |    Stream.Write WinHttp.responseBody
    |    Stream.SaveToFile FileName, 2 ' adSaveCreateOverWrite
    |    Stream.Close
    |End Sub";
    
    Попытка
        Scr.AddCode(ТекстМодуля);
        // Вызываем процедуру сохранения, передавая объект WinHttp и путь
        Scr.Run("SaveToFile", ПутьКФайлу, ОтправЧек);
        Сообщить("Файл успешно сохранен: " + ПутьКФайлу);
    Исключение
        Сообщить("Ошибка при сохранении файла: " + ОписаниеОшибки());
    КонецПопытки;
Иначе
    Сообщить("Ошибка запроса: " + ОтправЧек.status + " " + ОтправЧек.statusText);
КонецЕсли;

Разбор параметров ADODB.Stream

Выясним причину использования конкретных параметров в скрипте, так как они критичны для успешного сохранения PDF:

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

При работе с внешними API через 1С 7.7 следует учитывать еще несколько технических моментов:

1. Поддержка TLS 1.2: Современные сервисы (СБИС, Честный Знак и др.) требуют протокола шифрования TLS 1.2. Если ваш сервер работает на старой ОС (например, Windows Server 2008 R2), WinHttp может выдать ошибку соединения. В этом случае необходимо убедиться, что в операционной системе включена поддержка TLS 1.2 через реестр или установлены соответствующие обновления безопасности.

2. Обработка ошибок авторизации: Если сессия (Cookie) просрочена, сервер вернет 401 Unauthorized. Мы рекомендуем добавить блок проверки этого статуса и автоматический вызов функции авторизации, чтобы процесс получения PDF был полностью автономным.

3. Временные файлы: Не забудьте очищать временные файлы после того, как PDF был отправлен клиенту или распечатан, чтобы не занимать дисковое пространство на сервере 1С.

Использование связки WinHttp + MSScriptControl + ADODB.Stream является на текущий момент самым надежным "золотым стандартом" для работы с бинарными HTTP-ответами в 1С 7.7. Этот метод позволяет игнорировать устаревшие механизмы типизации встроенного языка и работать с данными напрямую через системные библиотеки Windows.

← На главную