Передача файлов между клиентской и серверной частью — одна из самых частых задач в разработке на платформе 1С:Предприятие 8.3. Однако просто «перекинуть» файл недостаточно. Важно учитывать формат передачи, нагрузку на память сервера и особенности интеграции с внешними системами. В этой статье мы подробно разберем, почему файлы могут «биться» при передаче, как правильно использовать Base64 и какие современные методы платформы сделают вашу работу эффективнее.
Разберем типичную ситуацию, с которой столкнулся автор темы. При получении двоичных данных на сервере и их преобразовании в строку Base64 для HTTP-запроса, файл на принимающей стороне оказывается поврежденным. Проанализируем причину. Метод 1С Base64Строка() работает по стандарту RFC 2045, который предписывает добавлять символы переноса строк (Символы.ПС) через каждые 72 символа. Если внешняя система (API) ожидает сплошную строку по стандарту RFC 4648, файл просто не соберется обратно.
Рассмотрим правильный способ подготовки тела запроса, если вы все же решили использовать Base64:
// На стороне сервера получаем данные из хранилища
ДвоичныеДанныеФайл = ПолучитьИзВременногоХранилища(АдресХранилища);
// Преобразуем в строку
Тело = Base64Строка(ДвоичныеДанныеФайл);
// ОБЯЗАТЕЛЬНО удаляем переносы строк для совместимости с большинством API
Тело = СтрЗаменить(Тело, Символы.ПС, "");
Тело = СтрЗаменить(Тело, Символы.ВК, ""); // На всякий случай убираем возврат каретки
HTTPЗапрос.УстановитьТелоИзСтроки(Тело);
Важный нюанс: использование Base64 увеличивает объем передаваемых данных примерно на 30–33%. Если вы передаете тяжелые файлы, это создает лишнюю нагрузку на сеть и оперативную память сервера.
Выясним, как сделать передачу более «кошерной». Вместо того чтобы конвертировать файл в строку, платформа 1С позволяет устанавливать тело HTTP-запроса напрямую из двоичных данных или даже из файла на диске. Это исключает проблемы с кодировкой и экономит ресурсы.
Разберем по шагам использование метода УстановитьТелоИзДвоичныхДанных():
ДвоичныеДанные напрямую в запрос.
// На сервере
ДвоичныеДанныеФайл = ПолучитьИзВременногоХранилища(АдресХранилища);
// Устанавливаем бинарное тело запроса без лишних преобразований
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеФайл);
// Не забываем указать правильный заголовок, чтобы сервер понял тип файла
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/octet-stream");
Этот метод гораздо надежнее, так как данные передаются «как есть», байт в байт.
Проанализируем современные возможности платформы. Начиная с версии 8.3.15, компания 1С унифицировала методы работы с файлами. Использование синхронных методов (таких как ПоместитьВоВременноеХранилище напрямую с путем к файлу) в мобильных и веб-клиентах может быть ограничено или приводить к «замиранию» интерфейса.
Рекомендуется использовать асинхронный метод НачатьПомещениеФайлаНаСервер(). Это позволяет пользователю продолжать работу с формой, пока файл загружается. Рассмотрим пример логики:
// На клиенте
ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершитьЗагрузкуФайла", ЭтотОбъект);
НачатьПомещениеФайлаНаСервер(ОписаниеОповещения, , , , УникальныйИдентификатор);
// В процедуре обратного вызова
&НаКлиенте
Процедура ЗавершитьЗагрузкуФайла(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Результат Тогда
// Передаем полученный Адрес на сервер для формирования HTTP-запроса
ОтправитьФайлПоHTTP(Адрес);
КонецЕсли;
КонецПроцедуры
Использование УникальныйИдентификатор формы крайне важно: это гарантирует, что временное хранилище будет очищено автоматически сразу после закрытия формы, предотвращая утечки памяти в процессе rphost.
Иногда файл нужно передать не во внешнюю систему, а сохранить внутри базы или передать между фоновыми заданиями. В этом случае рассмотрим применение объекта ХранилищеЗначений. Его преимущество в том, что он поддерживает автоматическое сжатие (ZIP) при передаче.
// Упаковываем со сжатием (уровень от 0 до 9)
ОбъектХранилище = Новый ХранилищеЗначений(ДвоичныеДанныеФайл, Новый СжатиеДанных(9));
// Теперь этот объект можно передать в параметр серверной функции
Это сокращает трафик между клиентом и сервером, особенно если передаются текстовые файлы или лог-файлы, которые хорошо сжимаются.
Если вы столкнулись с тем, что файл «не открывается» на стороне приемника, выполните проверку по списку:
ДвоичныеДанные.Размер() в 1С и размер файла, полученного сервером. Если в 1С размер больше, значит, вы забыли убрать символы переноса из Base64.binary, а не как form-data, если в 1С используете УстановитьТелоИзДвоичныхДанных().ДвоичныеДанные.Записать(ПутьКФайлу) перед отправкой. Если этот локальный файл открывается — проблема в настройках HTTP-запроса или внешней системы.Подводя итог, отметим: для грамотной передачи файлов в 1С следует отдавать предпочтение методу УстановитьТелоИзДвоичныхДанных(), всегда контролировать очистку временного хранилища через УникальныйИдентификатор и помнить о специфике RFC-стандартов при работе с Base64.