Как отправить ZIP-файл POST-запросом из 1С на сайт через COM-объект MSXML2.XMLHTTP?

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

В практике интеграции 1С с веб-сервисами часто возникает задача передачи не только текстовых данных в формате JSON или XML, но и бинарных файлов, например, ZIP-архивов с выгрузками. Если для версии 1С 8.3 существуют встроенные средства работы с HTTP-запросами, то для старых версий (1С 7.7, 8.0, 8.1) или при специфических требованиях к окружению программисты часто прибегают к использованию COM-объектов MSXML2.XMLHTTP или WinHttp.WinHttpRequest.5.1. Рассмотрим подробно, как реализовать передачу ZIP-файла, какие объекты для этого потребуются и с какими нюансами можно столкнуться.

Метод 1: Передача бинарных данных «как есть» (Raw Post Data)

Самая простая ситуация — когда принимающая сторона (сайт) готова принять содержимое файла непосредственно из тела POST-запроса. В этом случае файл не упаковывается в специальную структуру формы (multipart/form-data), а передается «сырым» потоком байтов. Разберем, как это реализовать с помощью связки объектов ADODB.Stream и MSXML2.XMLHTTP.

Основная сложность в 1С (особенно в версии 7.7) заключается в том, что обычные строковые переменные не могут корректно хранить бинарные данные, так как нулевой байт воспринимается как конец строки. Для обхода этого ограничения мы будем использовать объект ADODB.Stream, который умеет работать с данными в двоичном виде.

Проанализируем программный код для реализации этой задачи:


// Определяем параметры подключения
АдресURL = "http://ваш-сайт.ru/api/upload";
ПутьКФайлу = "C:\export.zip";

// 1. Используем ADODB.Stream для чтения файла в бинарном виде
Поток = СоздатьОбъект("ADODB.Stream");
Поток.Type = 1; // 1 = adTypeBinary (важный момент!)
Поток.Open();
Поток.LoadFromFile(ПутьКФайлу);

// 2. Создаем объект для HTTP запроса
// Можно использовать MSXML2.XMLHTTP или MSXML2.ServerXMLHTTP для серверных скриптов
HTTPЗапрос = СоздатьОбъект("Msxml2.XMLHTTP");
HTTPЗапрос.Open("POST", АдресURL, 0); // 0 = синхронный запрос

// 3. Устанавливаем заголовки
HTTPЗапрос.setRequestHeader("Content-Type", "application/zip");

// 4. Отправляем бинарное содержимое потока
HTTPЗапрос.Send(Поток.Read());

// Проверяем результат
Если HTTPЗапрос.status = 200 Тогда
    Сообщить("Файл успешно отправлен!");
Иначе
    Сообщить("Ошибка отправки. Статус: " + HTTPЗапрос.status);
    Сообщить("Ответ сервера: " + HTTPЗапрос.responseText);
КонецЕсли;

Поток.Close();

Важные моменты в этом коде:

  1. Установка Поток.Type = 1 обязательна. Это переводит объект в бинарный режим работы. По умолчанию используется текстовый режим, который повредит ZIP-архив.
  2. Метод Поток.Read() возвращает массив байтов (SafeArray), который объект XMLHTTP понимает и корректно передает в теле запроса.
  3. Заголовок Content-Type: application/zip сообщает серверу, что в теле запроса передается именно архив.

Метод 2: Использование WinHttp.WinHttpRequest.5.1 для повышения стабильности

Рассмотрим альтернативный вариант с использованием объекта WinHttp.WinHttpRequest.5.1. Этот объект считается более современным и гибким по сравнению с MSXML2.XMLHTTP. Проанализируем ситуацию: если передача файла занимает длительное время или требует работы через прокси-сервер, WinHttp справится лучше.

Выясним основные преимущества этого способа:

Пример реализации на WinHttp:


WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("POST", АдресURL, 0);

// Установка тайм-аутов: (Resolve, Connect, Send, Receive) в миллисекундах
WinHttp.SetTimeouts(30000, 30000, 60000, 60000);

WinHttp.SetRequestHeader("Content-Type", "application/zip");

// Читаем файл через ADODB.Stream, как в первом примере
Поток = СоздатьОбъект("ADODB.Stream");
Поток.Type = 1;
Поток.Open();
Поток.LoadFromFile(ПутьКФайлу);

WinHttp.Send(Поток.Read());

Сообщить("Статус: " + WinHttp.Status);

Понимание разницы между передачей файла и содержимого

Разберем типичную проблему, с которой сталкиваются разработчики при общении с веб-администраторами. Часто администратор сайта говорит: «Я ничего не получил», хотя 1С возвращает статус 200. Причина кроется в том, как сервер ожидает данные.

Raw Data (Методы выше): Вы отправляете байты файла в «теле» (body) HTTP-запроса. На языке PHP, например, получить эти данные можно через file_get_contents('php://input'). В этом случае файл не будет виден в привычном массиве $_FILES.

Multipart/form-data: Это формат, имитирующий загрузку файла через HTML-форму браузером. В этом случае файл упаковывается в «конверт» с разделителями (boundary). Если сервер ожидает именно этот формат, то просто отправить бинарный поток через Send() будет недостаточно — сервер не сможет распознать начало и конец файла.

Для реализации multipart/form-data в 1С 7.7 или при использовании COM-объектов, вам придется вручную формировать «тело» запроса, склеивая заголовок формы, бинарные данные файла и закрывающий разделитель. Это сложная задача, требующая побайтового объединения через ADODB.Stream.

Рекомендации для 1С версии 8.x

Если вы работаете на платформе 8.2 или 8.3, использование COM-объектов для этих целей считается избыточным. Посмотрим, как это решается штатными средствами платформы. Проанализируем использование объекта HTTPСоединение.

Начиная с версии 8.3.10, процесс стал максимально простым благодаря методу УстановитьТелоИзФайла объекта HTTPЗапрос. Это позволяет передавать файлы любого размера, не загружая их целиком в оперативную память 1С.


// Пример для 1С 8.3
Соединение = Новый HTTPСоединение("ваш-сайт.ru");
Запрос = Новый HTTPЗапрос("/api/upload");
Запрос.Заголовки.Вставить("Content-Type", "application/zip");

// Самый эффективный способ:
Запрос.УстановитьТелоИзФайла("C:\export.zip");

Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Сообщить(Ответ.КодСостояния);

Отладка и возможные ошибки

Рассмотрим причины, по которым отправка может не сработать:

  1. Ограничение размера на сервере: В настройках веб-сервера (например, в php.ini параметры post_max_size и upload_max_filesize или в Nginx client_max_body_size) может стоять лимит, меньший, чем ваш ZIP-файл.
  2. Тайм-аут: Если файл большой, соединение может разорваться до завершения передачи. Используйте WinHttp и увеличивайте время ожидания.
  3. Кодировка заголовков: Если в URL или заголовках передаются кириллические символы (например, имя файла), их необходимо предварительно кодировать в URL Encode.
  4. Отсутствие прав: Убедитесь, что у пользователя, под которым запущена 1С, есть права на чтение файла с диска и доступ к интернету через указанный порт.

Таким образом, для успешной отправки ZIP-файла из 1С с помощью MSXML2.XMLHTTP ключевым является использование ADODB.Stream для корректного чтения бинарных данных и правильная установка заголовков запроса. Если принимающая сторона требует сложный формат передачи (с именами полей и метаданными), стоит рассмотреть вариант передачи файла в строке Base64 внутри JSON-пакета, хотя это и увеличит объем трафика на 33%.

← На главную