Как скачать PDF-файл с HTTP-сервиса 1С через PHP (Битрикс) с Basic-авторизацией и показать в браузере?

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

Часто при интеграции 1С с веб-сайтами (например, на базе 1С-Битрикс) возникает задача: получить сформированный печатный документ (счет, акт, накладную) в формате PDF напрямую из HTTP-сервиса 1С и сразу же отобразить его пользователю в браузере. Разберем по шагам, как правильно настроить авторизацию, получить двоичные данные файла и вывести их на экран без промежуточного сохранения на сервере сайта.

Шаг 1. Получение файла из 1С через cURL с Basic-авторизацией

Для обращения к HTTP-сервису 1С из PHP чаще всего используется библиотека cURL. Поскольку сервис 1С обычно закрыт паролем, нам необходимо передать данные для авторизации. Рассмотрим рабочий вариант кода, где мы формируем заголовок Authorization: Basic.

Для передачи учетных данных мы кодируем связку логина и пароля в формат Base64 и отправляем в виде HTTP-заголовка. Проанализируем пример кода:


$user = "1";
$password = "1";    
$base64 = base64_encode("$user:$password");   

$headers = Array();
array_push($headers, 'Content-Type: application/x-www-form-urlencoded');
array_push($headers, 'Authorization: Basic ' . $base64);

$curl = curl_init();
$uri = "http://domen.online/UT1/hs/CreatePDF/";

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $uri);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_HEADER, false);

$response = curl_exec($curl);

В этом примере мы указываем параметр CURLOPT_RETURNTRANSFER как true. Это крайне важно, так как мы хотим получить двоичные данные PDF-файла в переменную $response, а не выводить их сразу в стандартный поток (что привело бы к ошибке отображения).

Альтернативный способ авторизации: cURL имеет встроенную опцию CURLOPT_USERPWD, которая выполняет ту же работу под капотом. Если вы используете её, следите за тем, чтобы не брать переменную с URL в одинарные кавычки, иначе cURL попытается перейти по строке "$url", а не по фактическому адресу.

Шаг 2. Вывод PDF-файла в браузере (Inline-отображение)

Итак, в переменной $response у нас теперь хранятся двоичные данные PDF. Если мы просто выведем эту переменную через echo, браузер покажет "кракозябры" (исходный код PDF, начинающийся с %PDF-1.7 и прочих служебных символов). Чтобы браузер понял, что это PDF-документ, и открыл его в своем встроенном просмотрщике, нам необходимо передать правильные HTTP-заголовки.

Рассмотрим код, который необходимо выполнить сразу после получения ответа от 1С:


$filename = "bill.pdf";

// Указываем тип контента
header('Content-type: application/pdf');

// Указываем, что файл нужно открыть в браузере (inline), а не скачивать (attachment)
header('Content-Disposition: inline; filename="' . $filename . '"');

header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . strlen($response));
header('Accept-Ranges: bytes');

// Выводим содержимое файла
echo $response;

Ключевой заголовок здесь — Content-Disposition: inline. Именно он заставляет браузер открыть файл на всю страницу. Если бы мы хотели принудительно заставить пользователя скачать файл на жесткий диск, мы бы использовали значение attachment.

Шаг 3. Решение проблем с выводом в 1С-Битрикс ("кракозябры" вместо PDF)

Даже если вы правильно написали код из первых двух шагов, при работе в системе 1С-Битрикс вы можете столкнуться с тем, что вместо красивого документа выводится текст с бинарным мусором. Проанализируем причину этой популярной ошибки.

Проблема кроется в попадании сторонних символов в буфер вывода до того, как отправляются заголовки header(). Это может быть:

  1. Обычные пробелы или пустые строки: Если перед открывающим тегом <?php< в вашем скрипте стоит хотя бы один пробел, он отправляется в браузер. Сервер при этом автоматически отправляет заголовок Content-Type: text/html, и наши заголовки PDF игнорируются или ломаются.
  2. Подключение стандартного пролога Битрикс: Если вы используете функцию require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");, Битрикс начинает выводить шапку сайта (HTML-каркас). Двоичные данные PDF смешиваются с HTML, что полностью разрушает структуру документа.

Как правильно отдавать файлы в Битрикс:

Во-первых, для служебных скриптов (отдача файлов, обработчики AJAX-запросов) необходимо использовать только служебный пролог, который инициализирует ядро системы, но не выводит визуальную часть:


require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

Во-вторых, хорошей и надежной практикой является принудительная очистка буфера вывода перед отправкой файла. Для этого перед блоком с header(...) вызовем функцию очистки:


// Очищаем весь случайный вывод (пробелы, переносы строк, возможные нотисы)
while (ob_get_level()) {
    ob_end_clean();
}

// Теперь можно смело отправлять заголовки
header('Content-type: application/pdf');
// ... остальные заголовки
echo $response;
exit; // Обязательно прерываем скрипт, чтобы дальше ничего не вывелось

Используя этот подход, мы гарантируем, что браузер получит чистый поток байтов PDF-файла без примеси HTML-тегов или невидимых пробелов. Это позволит открыть печатную форму напрямую из 1С в интерфейсе сайта плавно и без создания временных файлов на диске веб-сервера.

← На главную