Разработка и Конфигурация · 13 мин
1С: как передать файл с клиента на сервер
Как передать файл с клиента на сервер в 1С: ПоместитьФайл, НачатьПомещениеФайла, временное хранилище, передача через ДвоичныеДанные. Примеры кода и типичные ошибки.
В клиент-серверном режиме работы 1С клиентское приложение и сервер выполняются на разных машинах, поэтому файл, выбранный пользователем на своём компьютере, серверу напрямую недоступен. Попытка прочитать файл на сервере по локальному пути клиента — одна из самых частых ошибок начинающих разработчиков: сервер ищет файл в собственной файловой системе и либо не находит его, либо, что хуже, открывает другой файл с тем же именем.
Платформа 1С:Предприятие предлагает несколько штатных механизмов передачи: помещение файла во временное хранилище с клиента, асинхронные методы для тонкого и веб-клиента, а также передачу содержимого через параметры серверных вызовов. Выбор зависит от типа клиента, размера файла и того, нужна ли интерактивность (диалог выбора файла).
Ниже разобраны рабочие способы передачи файла с клиента на сервер с примерами кода, ограничениями каждого подхода и типичными ошибками. Материал ориентирован на платформу 8.3 с управляемыми формами, но общие принципы применимы и к обычным формам.
Почему нельзя просто прочитать файл на сервере
В файловом режиме работы клиент и «сервер» фактически выполняются в одном процессе на одной машине, поэтому код вида ДвоичныеДанные = Новый ДвоичныеДанные("C:\Документы\файл.pdf") работает независимо от того, где он написан. Это создаёт ложное ощущение, что путь к файлу доступен отовсюду.
В клиент-серверном варианте сервер 1С работает на отдельном компьютере, часто под Linux, с собственной файловой системой и собственными правами доступа. Путь C:\Документы\файл.pdf для сервера либо не существует, либо указывает на его локальный диск. Кроме того, директива компиляции &НаСервере означает, что код выполняется в контексте сервера и не имеет доступа к клиентской машине в принципе.
Отсюда правило: файл нужно сначала физически передать на сервер — либо через временное хранилище, либо передав его содержимое (двоичные данные, поток, строку Base64) параметром серверного вызова. Чтение по пути допустимо только если файл уже лежит на сервере или в сетевой папке, доступной серверу.
Передача файла через временное хранилище
Временное хранилище — штатный механизм платформы для передачи данных между клиентом и сервером в рамках сеанса. Клиент помещает файл в хранилище и получает адрес (строку вида UUID), а сервер по этому адресу извлекает данные. Это основной и рекомендуемый способ для толстого клиента и случаев, когда используется модальный или синхронный режим.
Синхронный вариант: ПоместитьФайл
Метод ПоместитьФайл доступен в толстом клиенте и при включённом режиме использования модальности. Он принимает адрес хранилища, путь к файлу и параметры интерактивности:
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
АдресХранилища = "";
НачатьПомещениеФайла = ПоместитьФайл(АдресХранилища, , , Истина, УникальныйИдентификатор);
Если Не АдресХранилища = "" Тогда
ОбработатьФайлНаСервере(АдресХранилища);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ОбработатьФайлНаСервере(АдресХранилища)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("pdf");
ДвоичныеДанные.Записать(ИмяВременногоФайла);
// дальнейшая обработка файла на сервере
КонецПроцедуры
Обратите внимание на третий параметр УникальныйИдентификатор формы: он привязывает данные к времени жизни формы, иначе хранилище очистится после очередного серверного вызова, и ПолучитьИзВременногоХранилища вернёт ошибку или Неопределено.
Асинхронный вариант: НачатьПомещениеФайла
В тонком и веб-клиенте синхронные вызовы работы с файловой системой запрещены, поэтому используется НачатьПомещениеФайла с описанием оповещения. Результат приходит в отдельную процедуру:
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект);
НачатьПомещениеФайла(ОписаниеОповещения, , , Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, Адрес, ВыбранноеИмяФайла, ДопПараметры) Экспорт
Если Результат Тогда
ОбработатьФайлНаСервере(Адрес, ВыбранноеИмяФайла);
КонецЕсли;
КонецПроцедуры
- 1На клиенте вызовите НачатьПомещениеФайла с описанием оповещения и УникальныйИдентификатор формы
- 2В процедуре оповещения проверьте Результат и передайте полученный адрес хранилища в серверную процедуру
- 3На сервере получите данные через ПолучитьИзВременногоХранилища(Адрес)
- 4При необходимости запишите двоичные данные во временный файл и обработайте
- 5После обработки удалите данные: УдалитьИзВременногоХранилища(Адрес)
Передача содержимого файла без временного хранилища
Для небольших файлов допустимо прочитать содержимое на клиенте и передать его параметром серверного вызова. Платформа умеет сериализовать значение типа ДвоичныеДанные, поэтому его можно передавать напрямую:
&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДопПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Тогда
Возврат;
КонецЕсли;
ДвоичныеДанные = Новый ДвоичныеДанные(ВыбранныеФайлы[0]);
ОбработатьНаСервере(ДвоичныеДанные);
КонецПроцедуры
У этого подхода есть ограничения. Весь файл целиком читается в память клиента, затем сериализуется и передаётся по каналу связи, что для файлов в десятки и сотни мегабайт даёт заметную нагрузку и может завершиться ошибкой нехватки памяти. Кроме того, конструктор Новый ДвоичныеДанные(Путь) в тонком и веб-клиенте требует подключения расширения работы с файлами.
Ориентир прост: файлы до нескольких мегабайт можно передавать параметром; всё крупнее — надёжнее через временное хранилище, которое платформа передаёт более экономно. Точный порог зависит от канала связи и настроек кластера, поэтому для больших файлов стоит проверить поведение на реальной инфраструктуре.
Сравнение вариантов
Универсальный способ для любого клиента и больших файлов; требует контроля времени жизни хранилища и очистки
Простой код для небольших файлов; весь файл грузится в память и сериализуется, не подходит для больших объёмов
Асинхронная загрузка в хранилище с минимальным кодом; требует аккуратной работы с оповещениями
Подходит для регламентных загрузок без клиента; требует настройки прав и не работает для произвольных файлов пользователя
Особенности тонкого и веб-клиента
Тонкий и веб-клиент работают с файловой системой только через расширение работы с файлами и только асинхронно. Перед вызовом методов вроде НачатьПомещениеФайла с интерактивным диалогом платформа сама предложит установить расширение, но при программном чтении файлов проверку стоит выполнить явно через НачатьПодключениеРасширенияРаботыСФайлами.
В веб-клиенте дополнительно действуют ограничения браузера: диалог выбора файла обязателен, произвольный путь указать нельзя, а размер передаваемого файла может ограничиваться настройками веб-сервера (например, лимитом тела запроса). Если загрузка больших файлов через веб-клиент обрывается, проверяйте в первую очередь настройки веб-сервера и публикации, а не код 1С.
Ещё одна тонкость: в веб-клиенте параметр «ИмяФайла» в оповещении содержит только имя файла без полного пути — браузер не отдаёт путь из соображений безопасности. Если логика обработки зависит от каталога, его придётся запрашивать у пользователя отдельно.
Обратная передача: файл с сервера на клиент
Обратная задача решается симметрично: сервер помещает данные во временное хранилище (ПоместитьВоВременноеХранилище), а клиент получает их по адресу и сохраняет через НачатьПолучениеФайлов или ПолучитьФайл:
&НаСервере
Функция ПодготовитьФайл()
ДвоичныеДанные = СформироватьОтчетВФайл(); // ваша логика
Возврат ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура СкачатьФайл(Команда)
Адрес = ПодготовитьФайл();
ПолучаемыеФайлы = Новый Массив;
ПолучаемыеФайлы.Добавить(Новый ОписаниеПередаваемогоФайла("Отчет.xlsx", Адрес));
НачатьПолучениеФайлов(Новый ОписаниеОповещения("ПослеПолучения", ЭтотОбъект), ПолучаемыеФайлы, , Истина);
КонецПроцедуры
И здесь важен третий параметр ПоместитьВоВременноеХранилище — идентификатор формы. Без него адрес станет недействительным после завершения серверного вызова, и клиент получит ошибку «Ошибка передачи данных» или пустой результат.
Типичные ошибки и как их диагностировать
Большинство проблем при передаче файлов сводится к нескольким повторяющимся причинам. Знание симптомов позволяет быстро локализовать проблему без долгой отладки.
Для диагностики полезно проверить, где именно возникает сбой: на этапе помещения (клиент), при вызове сервера (канал связи) или при извлечении (хранилище). Временно добавьте вывод размера данных и адреса хранилища в журнал регистрации — это сразу показывает, дошёл ли файл до сервера.
Как проверить результат
Непустая строка с UUID
Пустая строка или Результат = Ложь
Возвращает ДвоичныеДанные ненулевого размера
Неопределено или исключение
Открывается и совпадает по размеру с исходным
Нулевой размер, повреждённое содержимое
Работает стабильно, память сеанса не растёт
Ошибки со второго раза, рост потребления памяти
Безопасность и ограничения
Передаваемый от клиента файл нельзя считать доверенным. Если серверная обработка записывает файл на диск, формируйте имя файла сами через ПолучитьИмяВременногоФайла, а не берите его из клиентских данных: в имени могут быть символы обхода каталога. То же относится к расширению — проверяйте его по белому списку, если дальше файл будет обрабатываться внешними средствами.
Ограничьте максимальный размер загружаемого файла на уровне прикладного кода: проверка размера двоичных данных до начала обработки защищает сервер от исчерпания памяти при случайной или злонамеренной загрузке очень большого файла. Для массовых загрузок (обмены, импорт) рассмотрите фоновое выполнение через ДлительныеОперации, чтобы не блокировать сеанс пользователя и не упираться в таймауты вызовов.
Что важно запомнить
Файл с клиента на сервер передаётся содержимым, а не путём: основной способ — временное хранилище (НачатьПомещениеФайла + ПолучитьИзВременногоХранилища), для маленьких файлов допустимы ДвоичныеДанные параметром. Всегда передавайте УникальныйИдентификатор формы в хранилище, используйте асинхронные методы в тонком и веб-клиенте и очищайте хранилище после обработки.
Частые вопросы
Чем временное хранилище отличается от обычной передачи параметром?
Временное хранилище размещает данные на сервере отдельно от вызова и передаёт клиенту только адрес, что экономнее для больших файлов и позволяет обращаться к данным из нескольких серверных вызовов. Передача параметром сериализует данные внутри одного вызова — проще в коде, но тяжелее по памяти и трафику.
Почему ПолучитьИзВременногоХранилища возвращает Неопределено?
Чаще всего адрес уже недействителен: при помещении не был указан УникальныйИдентификатор формы, и хранилище очистилось после завершения предыдущего серверного вызова. Реже — адрес получен в другом сеансе или данные уже удалены вручную.
Можно ли передать файл в фоновом задании?
Фоновое задание выполняется на сервере и не имеет доступа к клиентской файловой системе. Сначала передайте файл на сервер любым способом (обычно через временное хранилище), а затем запускайте фоновое задание, передав ему адрес хранилища или путь к уже записанному на сервере файлу.
Как передать сразу несколько файлов?
Используйте НачатьПомещениеФайлов — это асинхронный метод для пакетной передачи: в оповещение приходит массив описаний помещённых файлов, каждый со своим адресом хранилища. На сервере обрабатывайте адреса в цикле, не забывая очищать хранилище по каждому из них.
Работает ли передача файлов в мобильном клиенте?
Да, но с ограничениями платформы: доступны асинхронные методы помещения и получения файлов, а выбор файла выполняется через средства мобильной ОС. Проверяйте доступность конкретных методов в синтакс-помощнике для мобильной платформы — набор отличается от настольного клиента.
Что делать, если большой файл не загружается через веб-клиент?
Проверьте ограничения на пути запроса: лимит размера тела запроса в настройках веб-сервера, таймауты прокси и публикации. Если лимиты поднять нельзя, перенесите загрузку в тонкий клиент или организуйте обмен через сетевой каталог, доступный серверу 1С.