Как правильно передать PDF-файл из 1С на сайт через HTTP-сервис в формате Base64 без повреждения данных?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Передача бинарных данных, таких как PDF-документы, счета или акты, из 1С на веб-сайт через HTTP-сервисы — это стандартная задача в современной разработке. Однако часто программисты сталкиваются с тем, что файл «долетает» до сервера поврежденным: он не открывается, имеет нулевой размер или выдает ошибку структуры при попытке чтения. В этой статье мы подробно разберем, как правильно реализовать этот процесс на стороне 1С и PHP, проанализируем типичные ошибки и выясним, почему файлы могут «биться» при передаче. При работе с популярными торговыми площадками вместо написания собственных сервисов часто применяют готовые модули интеграции 1С с маркетплейсами для управления заказами и товарами.

Формирование данных на стороне 1С: работа с потоками и Base64

Рассмотрим классический способ подготовки PDF-файла внутри 1С. В современных версиях платформы (начиная с 8.3.13) для работы с данными в памяти удобно использовать объект ПотокВПамяти. Это позволяет избежать создания временных файлов на диске сервера, что ускоряет работу и повышает безопасность.

Проанализируем пример кода 1С, который формирует PDF из табличного документа и кодирует его в строку Base64:


// Создаем поток в оперативной памяти
ПотокФайла = Новый ПотокВПамяти();    

// Записываем табличный документ в поток в формате PDF
ТабДокумент.Записать(ПотокФайла, ТипФайлаТабличногоДокумента.PDF);

// Получаем бинарные данные из закрытого потока
ДвоичныеДанныеПечати = ПотокФайла.ЗакрытьИПолучитьДвоичныеДанные();

// Кодируем данные в строку Base64 для передачи в JSON-пакете
СтрокаBase64 = Base64Строка(ДвоичныеДанныеПечати);

// Помещаем в структуру для отправки (например, через JSON)
Ответ = Новый Структура;
Ответ.Вставить("FileName", "invoice.pdf");
Ответ.Вставить("PrintForm", СтрокаBase64);

Важный нюанс: функция Base64Строка() в 1С формирует одну сплошную строку без переносов. Если вы используете старые релизы платформы или специфические настройки записи, убедитесь, что данные действительно сбрасываются из буфера в поток перед получением двоичных данных.

Прием и декодирование на стороне PHP

Теперь разберем, как эти данные принимает PHP-скрипт. Типичная ошибка заключается в том, что разработчики просто вызывают base64_decode(), не учитывая особенности передачи данных через HTTP-протокол. Посмотрим на стандартный код обработки:


$data = $requestData['PrintForm']; // Получаем строку из JSON
$decoded = base64_decode($data);
$file = 'invoice.pdf';

// Сохраняем файл на сервере
if (file_put_contents($file, $decoded)) {
    // Дальнейшая логика отправки файла в браузер или сохранения
}

Если на этом этапе PHP сообщает, что файл поврежден, хотя в 1С обратное преобразование (из Base64 обратно в ДвоичныеДанные) проходит успешно, значит, проблема в «транспорте» или интерпретации строки.

Почему PDF может повреждаться: неочевидные причины

Выясним основные причины, по которым структура файла может нарушаться в процессе передачи между 1С и сайтом. При отсутствии возможности настроить стабильный обмен через API задачу решает роботизированное взаимодействие с сайтами и формирование документов.

  1. Проблема символа «плюс» (+): Если вы передаете Base64-строку не в теле JSON (application/json), а как параметр POST-запроса (application/x-www-form-urlencoded), PHP автоматически заменяет все символы «+» на пробелы. Это мгновенно портит файл. Решение: всегда используйте trim() и принудительную замену пробелов обратно на плюсы: $data = str_replace(' ', '+', $data);.
  2. Служебные символы и переносы строк: Иногда при передаче через прокси-серверы или при использовании определенных библиотек HTTP-запросов длинная строка Base64 может разбиваться на части символами переноса строки (LF/CRLF). Решение: очищайте строку от лишних символов перед декодированием: $data = str_replace(["\r", "\n", " "], '', $data);.
  3. Padding (символы «=»): Строка Base64 должна заканчиваться специальными символами выравнивания =. Если при копировании или обрезке данных в памяти эти символы теряются, декодер может не распознать конец файла корректно. Именно на это указывал один из разработчиков в обсуждении: «Окончание файла иное — заканчивается на знак =».
  4. Лимиты памяти и POST-запроса: PDF-файлы в кодировке Base64 весят на 33% больше оригинала. Если ваш файл весит 10 Мб, в строке он будет занимать около 13.5 Мб. Проверьте параметры memory_limit и post_max_size в php.ini. Если лимит превышен, PHP просто «откусит» кусок данных, и файл будет нечитаемым.

Контроль целостности: использование хеширования

Чтобы точно определить, на чьей стороне происходит искажение данных, мы рекомендуем использовать контрольные суммы (хеши). Рассмотрим, как добавить проверку MD5 в процесс обмена.

В 1С вычислим хеш перед отправкой:


Хеширование = Новый ХешированиеДанных(СтандартныйАлгоритмХеширования.MD5);
Хеширование.Добавить(ДвоичныеДанныеПечати);
ХешСумма = НРег(СтрЗаменить(Строка(Хеширование.ХешСумма), " ", ""));
Ответ.Вставить("MD5", ХешСумма);

В PHP проверим хеш после декодирования:


$receivedHash = $requestData['MD5'];
$actualHash = md5($decoded);

if ($receivedHash !== $actualHash) {
    die("Ошибка: данные были повреждены при передаче!");
}

Если хеши не совпадают, значит, проблема в передаче строки (прокси, кодировка URL, обрезка строки). Если совпадают, но файл не открывается — проблема в методе формирования PDF в 1С (например, пустой табличный документ). Для автоматической подготовки файлов к отправке также применяется автоматическое формирование счетов и договоров в 1С на основе входящих заявок.

Рекомендация: переход на Multipart/form-data

Несмотря на популярность передачи файлов в JSON через Base64, этот метод считается менее эффективным для «тяжелых» PDF. Мы рекомендуем рассмотреть альтернативный вариант — использование multipart/form-data. Это позволит передавать файл как «настоящие» двоичные данные, экономя трафик и избегая проблем с кодированием строк.

В 1С это реализуется через объект HTTPЗапрос и метод УстановитьТелоИзДвоичныхДанных(), где файл передается в чистом виде, а метаданные (имя файла, ID) — в заголовках или отдельных частях запроса.

Подведем итог: если вы столкнулись с проблемой нечитаемости PDF, в первую очередь проверьте корректность завершения строки (символы =), очистите строку на стороне PHP от пробелов и переносов, а также убедитесь в отсутствии автоматической замены знака + на пробел. Использование MD5-хеша позволит вам локализовать ошибку в кратчайшие сроки.

← На главную