Интеграция 1С с веб-сервисами — это одна из наиболее частых задач при построении современных экосистем автоматизации. Одной из самых распространенных проблем является передача файлов (изображений, PDF-документов) на сервер под управлением PHP. В этой статье мы подробно разберем, как правильно сформировать запрос на стороне 1С и как корректно принять его на стороне PHP, чтобы избежать потери данных и ошибок 404 или 500.
Проанализируем исходный код, который часто используют начинающие разработчики. Первая и самая важная ошибка кроется в инициализации объектов HTTPСоединение и HTTPЗапрос. Посмотрим на этот фрагмент:
HTTPСоединение = Новый HTTPСоединение("report.tmotor.ru"); // Только имя сервера
// ОШИБКА: Нельзя писать полный URL в HTTPЗапрос
HTTPЗапрос = Новый HTTPЗапрос("report.tmotor.ru/report/php/tel_upload.php", ЗаголовокHTTP);
Выясним причину проблемы: объект HTTPСоединение отвечает за установку связи с хостом (сервером), а HTTPЗапрос должен содержать только относительный путь к ресурсу на этом сервере. Правильный подход выглядит так:
HTTPСоединение, указывая только домен (например, "report.tmotor.ru").HTTPЗапрос, указывая путь от корня сайта (например, "/report/php/tel_upload.php").Если в HTTPЗапрос передать строку, начинающуюся с имени домена или http://, сервер может вернуть ошибку, так как запрос будет сформирован некорректно на уровне протокола.
Для передачи файлов используется формат multipart/form-data. Этот формат требует строгого соблюдения структуры разделителей (boundary). Разберем по шагам, как правильно собрать тело запроса в 1С. Важно помнить, что протокол HTTP требует использования последовательности символов ВК + ПС (возврат каретки и перевод строки) в качестве разделителя строк, в то время как стандартный Символы.ПС в 1С — это только один символ перевода строки.
Рассмотрим пример правильного формирования текстового файла для отправки:
Разделитель = "----" + СтрЗаменить(Строка(Новый УникальныйИдентификатор()), "-", "");
ИмяФайлаТела = ПолучитьИмяВременногоФайла();
ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаТела, КодировкаТекста.UTF8, Символы.ВК + Символы.ПС);
ЗаписьТекста.ЗаписатьСтроку("--" + Разделитель);
// Важно: name="fileToUpload" — это ключ, по которому PHP найдет файл в массиве $_FILES
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""fileToUpload""; filename=""image.png""");
ЗаписьТекста.ЗаписатьСтроку("Content-Type: image/png");
ЗаписьТекста.ЗаписатьСтроку(""); // Пустая строка перед данными
// Здесь мы можем записать бинарные данные или Base64
ЗаписьТекста.Записать(Base64Строка(ДвоичныеДанныеФайла));
ЗаписьТекста.ЗаписатьСтроку("");
ЗаписьТекста.ЗаписатьСтроку("--" + Разделитель + "--");
ЗаписьТекста.Закрыть();
Проанализируем ситуацию с Base64. Многие программисты 1С привыкли кодировать двоичные данные в Base64. Однако, если вы используете multipart/form-data, это не всегда эффективно, так как объем данных увеличивается на 33%. Если ваш PHP-скрипт умеет работать с бинарными данными, лучше передавать файл «как есть», используя Поток или комбинируя файлы.
Очень важно понимать, как PHP обрабатывает входящий запрос. Если в 1С вы указали Content-Disposition: form-data; name="file_data", то данные попадут в массив $_POST['file_data']. Если же вы добавили параметр filename="image.png", то PHP воспримет это как загрузку файла и поместит информацию в массив $_FILES['file_data'].
Посмотрим на пример PHP-скрипта, который корректно сохраняет файл, отправленный из 1С:
<?php
$target_dir = "uploads/";
// Проверяем, пришел ли файл через стандартный механизм загрузки
if(isset($_FILES["fileToUpload"])) {
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
echo "Файл успешно сохранен на сервере.";
} else {
echo "Ошибка при перемещении временного файла.";
}
} else {
echo "Данные о файле не получены.";
}
?>
Если вы все же решили передавать данные в формате Base64 внутри обычного поля POST, не забудьте на стороне PHP выполнить декодирование перед сохранением, иначе файл будет поврежден:
$encodedData = $_POST['file_data'];
$decodedData = base64_decode($encodedData);
file_put_contents("image.png", $decodedData);
Современные веб-сайты работают по протоколу HTTPS. В этом случае обычного объекта HTTPСоединение будет недостаточно, так как 1С должна проверить SSL-сертификат сервера. Для этого необходимо использовать объект ЗащищенноеСоединениеOpenSSL.
Разберем пример инициализации безопасного соединения:
Защита = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
HTTPСоединение = Новый HTTPСоединение("report.tmotor.ru", 443, , , , 30, Защита);
Без этого параметра 1С выдаст ошибку "Удаленный узел не прошел проверку", и запрос даже не дойдет до вашего PHP-скрипта.
Если код написан, но файл не появляется на сервере, выполним следующие шаги:
www-data или apache).upload_max_filesize и post_max_size. Если файл из 1С больше этих лимитов, сервер молча отбросит запрос.file_put_contents('debug.txt', print_r($_FILES, true));. Это позволит увидеть, какие данные реально доходят до сервера.Соблюдение этих правил позволит вам создать надежный механизм обмена данными между 1С:Предприятие и веб-сайтом, обеспечив целостность передаваемой информации и корректную обработку на стороне сервера.