Вводные
- База 1С с возможностью публикации HTTP сервиса.
- Отсутствие возможности разместить статические файлы в папке web сервера
- Web проект поставляется в 1С собранным, для тестов использовал AdminLTE
- Размещение файлов в макетах обработки не удобно (пример с макетами)
Вариант реализации
Запаковать сборку в zip архив, прикрепить двоичные данные к именованной настройке подсистемы.
При запросе к HTTP сервису искать настройку по адресу, при нахождении настройки обращаться к общему модулю с свойством "Повторное использование возвращаемых значений" = На время сеанса.
В рамках модуля с повторным использованием
- распаковываю архив,
- получаю список распакованных файлов,
- помещаю каждый из них во временное хранилище на время работы сеанса.
- относительные пути к файлам с адресами во временном хранилище помещаю в таблицу значений с индексом
В рамках обработчика ищу строку по соответствию относительного пути, если нахожу, то отдаю код 200 с телом из двоичных данных иначе 404.
http_serv_ОбработчикСервиса
Функция ОбработатьЗапрос(Запрос) Экспорт
СтрокаЗапроса = Запрос.ОтносительныйURL;
МассивАдресЗапроса = СтрРазделить(СтрокаЗапроса, "/");
НаименованиеУзла = МассивАдресЗапроса[1];
Если ПустаяСтрока(НаименованиеУзла) Тогда
Возврат СформироватьОтвет(404, СтрокаЗапроса);
КонецЕсли;
Узел = http_serv_ПовторноеИспользование.ПолучитьУзел(НаименованиеУзла);
Если Не ЗначениеЗаполнено(Узел) Тогда
Возврат СформироватьОтвет(404, СтрокаЗапроса);
КонецЕсли;
ТаблицаСтатическихДанных = http_serv_ПовторноеИспользование.ПолучитьТаблицуСтатическихДанных(НаименованиеУзла);
СтрокаЗапросаСокр = Сред(СтрокаЗапроса, СтрДлина(НаименованиеУзла) + 3);
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("ИмяФайла", СтрокаЗапросаСокр);
нСтроки = ТаблицаСтатическихДанных.НайтиСтроки(ПараметрыОтбора);
Если нСтроки.Количество() = 0 Тогда
Возврат СформироватьОтвет(404, СтрокаЗапросаСокр);
КонецЕсли;
ДвоичныеДанные = ПолучитьИзВременногоХранилища(нСтроки[0].АдресВХранилище);
Возврат СформироватьОтвет(200, ДвоичныеДанные);
КонецФункции
Функция СформироватьОтвет(КодСостояния = 200, Данные = "")
Ответ = Новый HTTPСервисОтвет(КодСостояния);
Если ТипЗнч(Данные) = Тип("Строка") Тогда
Ответ.Заголовки.Вставить("Content-Type", "application/json");
Ответ.УстановитьТелоИзСтроки(Данные);
Иначе
Ответ.УстановитьТелоИзДвоичныхДанных(Данные);
КонецЕсли;
Возврат Ответ;
КонецФункции
http_serv_ПовторноеИспользование
Функция ПолучитьТаблицуСтатическихДанных(НаименованиеУзла) Экспорт
ТаблицаСтатическихДанных = Новый ТаблицаЗначений;
ТаблицаСтатическихДанных.Колонки.Добавить("ИмяФайла", Новый ОписаниеТипов("Строка"));
ТаблицаСтатическихДанных.Колонки.Добавить("АдресВХранилище", Новый ОписаниеТипов("Строка"));
Узел = ПолучитьУзел(НаименованиеУзла);
Если Не ЗначениеЗаполнено(Узел) Тогда
Возврат ТаблицаСтатическихДанных;
КонецЕсли;
ИмяАрхивногоФайла = ПолучитьИмяВременногоФайла("zip");
ДвоичныеДанные = Узел.СтатичныеДанные.Получить();
ДвоичныеДанные.Записать(ИмяАрхивногоФайла);
ПапкаНазначения = КаталогВременныхФайлов() + Строка(Новый УникальныйИдентификатор) + "\";
ЧтениеZIP = Новый ЧтениеZipФайла(ИмяАрхивногоФайла);
ЧтениеZIP.ИзвлечьВсе(ПапкаНазначения, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
МассивФайлов = НайтиФайлы(ПапкаНазначения,"*", Истина);
Для Каждого СтрИмяФайла Из МассивФайлов Цикл
ДвоичныеДанные = Новый ДвоичныеДанные(СтрИмяФайла.ПолноеИмя);
СтрСт = ТаблицаСтатическихДанных.Добавить();
СтрСт.ИмяФайла = СтрЗаменить(СтрИмяФайла.ПолноеИмя, ПапкаНазначения, "");
СтрСт.АдресВХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанные, Новый УникальныйИдентификатор)
КонецЦикла;
ТаблицаСтатическихДанных.Индексы.Добавить("ИмяФайла");
УдалитьФайлы(ИмяАрхивногоФайла);
УдалитьФайлы(ПапкаНазначения);
Возврат ТаблицаСтатическихДанных;
КонецФункции
Функция ПолучитьОбработчики(НаименованиеУзла) Экспорт
КонецФункции
Функция ПолучитьУзел(Наименование) Экспорт
Возврат Справочники.http_serv_НастройкиПодсистемы.НайтиПоРеквизиту("КорневойАдрес", Наименование);
КонецФункции
Проверка работоспособности
Опубликовал базу по адресу "http://localhost:8080/unf_demo", HTTP сервис "api_uni", корневой адрес в настройки подсистемы "test"
Apache 2.4(x64) Платформа 8.3.17(x64), конфигурация в режиме совместимости 8.3.14.
Параметры HTTP сервиса "Повторное использование сеансов" равно "Использовать автоматически", при установке в "Использовать" получаю ошибку "Не указан заголовок управления сеансами или куки с идентификатором сеанса.", возможно проблемы с сеансами из за включенной отладки на сервере.
Исходный тестовый файл 18 МБ, 1800+ файлов, Холодный старт 12 сек, повторный ответ в пределах 50 мсек.
Проект на GitHub ссылка
Итог
Через HTTP-сервис можно опубликовать статичные файлы, не "размазывая" их по макетам.
Благодарю за внимание.