Вставки HTML, CSS и JS
Пользовательские вставки позволяют подключать к пользовательской части обменника сторонние виджеты, чаты, системы аналитики, коды подтверждения, дополнительные стили и другие интеграции без изменения исходного кода и повторной сборки Frontend.
На новых серверах вставки хранятся в отдельном общем каталоге:
/var/www/iexexchanger/shared/frontend/ng-customРабота с файлами выполняется на сервере Frontend через SSH. Отдельного редактора пользовательских вставок в административной панели нет.
Как устроена система на новых серверах
Каталог ng-custom находится в общей директории shared, а не внутри конкретного релиза Frontend. Благодаря этому пользовательские файлы не заменяются при штатном обновлении или откате приложения.
Файлы доступны через основной домен Frontend:
https://ваш_домен/ng-custom/имя-файлаДомен Backend https://app.ваш_домен для пользовательских вставок не используется.
Установщик автоматически:
создаёт общий каталог
ng-custom;добавляет пять базовых файлов;
назначает безопасные права доступа;
подключает каталог к Nginx;
отключает просмотр содержимого каталога;
блокирует скрытые и PHP-подобные файлы;
добавляет заголовки, запрещающие сохранение устаревшей версии в кеше;
сохраняет каталог при обновлении Frontend.
Если штатное резервное копирование сервера включено, каталог входит в резервную копию общей директории /var/www/iexexchanger/shared.
Файлы пользовательских вставок
В каталоге находятся следующие базовые файлы:
client-scripts.js
Браузерный
Произвольный JavaScript и подключение внешних скриптов после запуска Frontend
client-snippets.html
Браузерный
HTML, CSS, теги <script>, <meta>, <link> и другие готовые фрагменты
ssr-head.html
SSR
Вставка перед закрывающим тегом </head>
ssr-body-start.html
SSR
Вставка сразу после открывающего тега <body>
ssr-body-end.html
SSR
Вставка перед закрывающим тегом </body>
Допускается создавать дополнительные статические файлы, например:
Они также будут доступны через /ng-custom/.
Все файлы внутри ng-custom, включая исходные SSR-фрагменты, считаются публичными. Никогда не сохраняйте в них пароли, приватные API-ключи, секретные токены, закрытые ключи или другие конфиденциальные данные.
Режимы работы
Браузерный режим и SSR работают независимо. Можно включить один режим или оба одновременно.
Браузерный
CLIENT_CUSTOM_SCRIPTS_ENABLED
После первого отображения Angular-приложения в браузере
SSR
CLIENT_CUSTOM_SSR_ENABLED
При формировании исходного HTML на сервере
Браузерный режим
Браузерный режим загружает:
Особенности режима:
файлы загружаются только в браузере;
пользовательский код не выполняется во время серверного рендеринга;
загрузка начинается после первого отображения Angular-приложения;
оба файла загружаются независимо и параллельно;
ошибка пользовательского файла записывается в консоль и не должна останавливать основную загрузку Frontend;
для работы после переходов между страницами доступен route-aware API;
локализованные варианты браузерных файлов автоматически не выбираются.
Не полагайтесь на порядок выполнения client-scripts.js и client-snippets.html. Если фрагменты зависят друг от друга, разместите зависимый код в одном файле или используйте событие iex:custom:ready.
SSR-режим
SSR-режим добавляет содержимое файлов непосредственно в исходный HTML-ответ.
JavaScript из SSR-файлов не выполняется процессом Node.js. Frontend только добавляет соответствующую разметку в HTML, после чего теги <script> выполняются браузером обычным способом.
SSR подходит для:
стилей, которые должны присутствовать уже в первом HTML;
кодов подтверждения сторонних сервисов;
элементов
<noscript>;тегов
<meta>и<link>;скриптов, которые должны находиться в определённой части документа.
SSR-вставки выполняются при полной загрузке страницы. Они не запускаются повторно при внутренних переходах Angular. Для личного кабинета и других CSR-страниц используйте браузерный режим и onPageReady().
Как выбрать режим для CSS
Разместите CSS в client-snippets.html, если стиль можно применить после первого отображения страницы.
Разместите CSS в ssr-head.html, если он должен находиться в исходном <head> и применяться как можно раньше.
Для большого объёма CSS создайте отдельный файл custom.css и подключите его через:
Включение при новой установке
До запуска новой установки режимы можно включить в /home/installer/install.yaml:
Если нужен только один режим, оставьте второе значение false.
Изменение install.yaml на уже установленном сервере само по себе не меняет работающий Frontend. На завершённой установке используются параметры из /etc/iexexchanger/frontend.env.
Во время активной установки, обновления, отката или восстановления не изменяйте install.yaml, frontend.env, Nginx и управляемые файлы. Дождитесь завершения операции.
Включение на установленном сервере
Для работы потребуются SSH-доступ и возможность выполнять команды через sudo.
Редактирование пользовательских файлов
Для редактирования используйте sudoedit:
Перед значительным изменением сохраните копию файла в защищённом каталоге вне /var/www/iexexchanger/shared/frontend/ng-custom.
Не храните резервные копии с расширениями .bak, .old или .copy внутри публичного каталога: такие файлы также могут стать доступными через сайт.
Не используйте права 777 и не меняйте владельца базовых файлов без необходимости. Установщик ожидает обычные файлы без символических ссылок и дополнительных жёстких ссылок.
Работа с JavaScript в браузерном режиме
JavaScript размещается в:
Код верхнего уровня выполняется сразу после загрузки файла. Рекомендуемая точка входа — функция window.IEX_CUSTOM_INIT.
Базовый шаблон:
Замените адрес сервиса и публичный идентификатор значениями, предоставленными поставщиком интеграции.
Параметр id предотвращает повторное добавление одного и того же <script> при переходах между страницами.
Пользовательский callback должен быть идемпотентным: повторное выполнение не должно создавать дублирующиеся кнопки, виджеты или обработчики событий.
Проверка синтаксиса JavaScript
Перед публикацией можно проверить синтаксис:
Эта команда проверяет синтаксис, но не подтверждает работу браузерного API или стороннего сервиса.
Работа с HTML и CSS в браузерном режиме
Готовые HTML-фрагменты размещаются в:
Файл может содержать:
Frontend обрабатывает верхнеуровневые элементы следующим образом:
<meta>,<link>,<style>и<title>перемещаются вdocument.head;обычная HTML-разметка добавляется в
body;теги
<script>пересоздаются и выполняются;скрипты внутри файла обрабатываются последовательно;
пустые текстовые узлы и HTML-комментарии пропускаются;
тег
<base>игнорируется.
Файл не проходит HTML-санитизацию. Его содержимое считается доверенным кодом владельца сервера.
Не вставляйте полный HTML-документ с тегами <html>, <head> и <body>. Добавляйте только нужные фрагменты.
Создание отдельного CSS-файла
Создайте файл:
Для нового файла скопируйте владельца и права с базового файла:
Подключите его в client-snippets.html или ssr-head.html:
Проверьте доступность:
API браузерного режима
При включённом браузерном режиме Frontend создаёт:
Текущая версия API:
API также передаётся аргументом в window.IEX_CUSTOM_INIT.
version
Версия API
Строка
readyState
Значение document.readyState в момент установки API
Без параметров
currentRoute()
Возвращает текущий адрес внутри Frontend
Без параметров
loadScript()
Загружает дополнительный JavaScript
URL и объект настроек
injectHtml()
Добавляет HTML и выполняет содержащиеся в нём скрипты
HTML и объект настроек
onReady()
Выполняет callback после готовности DOM
Функция
onRouteChange()
Подписывает callback на текущий маршрут и Angular-навигации
Функция и immediate
onPageReady()
Вызывает callback после отрисовки DOM текущей страницы
Функция и immediate
mount()
Возвращает или создаёт контейнер для интеграции
ID и объект настроек
safeRun()
Выполняет callback через защитный try/catch
Функция и подпись ошибки
Объект текущего маршрута
currentRoute(), onRouteChange() и onPageReady() используют объект:
url
Путь, параметры запроса и хеш
path
Только путь
search
Строка параметров запроса
hash
Хеш страницы
Пример результата:
Метод loadScript
Сигнатура:
Поддерживаемые настройки:
id
Предотвращает повторную загрузку скрипта с тем же ID
async
Управляет свойством script.async; по умолчанию true
defer
Управляет свойством script.defer; по умолчанию true
attributes
Добавляет data-*, integrity, crossorigin и другие атрибуты
Метод не ограничивает домены внешних скриптов. Пустые адреса и адреса с управляющими символами отклоняются.
Метод injectHtml
Сигнатура:
Параметр target принимает:
body;head;CSS-селектор существующего элемента.
Если элемент по CSS-селектору не найден, используется body.
Параметр wrapperId создаёт или повторно использует контейнер с указанным ID.
Методы onRouteChange и onPageReady
Оба метода возвращают функцию отписки:
По умолчанию immediate равен true, поэтому callback планируется сразу после регистрации. Затем callback вызывается при первоначальном route-ready событии и после Angular-навигаций.
Логика callback должна выдерживать повторные вызовы. Если подписка создаётся внутри IEX_CUSTOM_INIT и нужен только объединённый первоначальный сигнал после загрузки обоих пользовательских файлов, укажите:
Callbacks выполняются после двух кадров браузерной отрисовки, чтобы DOM личного кабинета и других CSR-страниц успел обновиться.
Метод mount
Метод создаёт постоянный контейнер для виджета:
Если элемент с таким ID уже существует, API возвращает его повторно.
Если target не найден, используется системный контейнер #iex-custom-root, а при его отсутствии — body.
Параметр clear: true очищает существующий контейнер перед повторным использованием.
События браузерного режима
Помимо API, Frontend отправляет браузерные события:
Событие
Когда отправляется
Содержимое event.detail
iex:custom:ready
После завершения попыток загрузки обоих пользовательских файлов
route
iex:route-ready
После первой загрузки и каждой Angular-навигации
reason и route
Подписка:
Для iex:route-ready поле reason содержит:
или:
Работа с SSR-вставками
SSR-файлы содержат готовые фрагменты HTML.
Вставка в head
Файл:
Содержимое добавляется перед </head>.
Подходящий формат:
Вставка в начало body
Файл:
Содержимое добавляется сразу после открывающего тега <body>.
Подходящий формат:
Вставка в конец body
Файл:
Содержимое добавляется перед </body>.
Подходящий формат:
Frontend автоматически оборачивает добавленное содержимое служебными комментариями:
Добавлять эти комментарии вручную не требуется. Они также защищают HTML от повторной вставки одного слота.
Файл, содержащий только пробелы или HTML-комментарии, считается пустым и не добавляется в страницу.
Не добавляйте тег <base> в SSR-файлы. В SSR-режиме разметка вставляется напрямую, поэтому <base> может изменить обработку всех относительных ссылок и нарушить маршрутизацию Frontend.
Мультиязычные SSR-вставки
Для разных языков можно создать подкаталоги внутри ng-custom:
В каждом подкаталоге можно разместить собственные версии:
Для SSR Frontend проверяет файлы в следующем порядке:
Подкаталог языка текущей страницы.
Подкаталог языка Frontend по умолчанию.
Корень общего каталога
ng-custom.
Например, для английской страницы и языка по умолчанию ru порядок будет следующим:
Используется первый существующий файл.
Если языковой файл существует, но содержит только пробелы или HTML-комментарии, слот для этого языка останется пустым. Переход к следующему файлу не выполняется. Это позволяет намеренно отключить отдельную SSR-вставку для конкретного языка.
Чтобы использовать общий вариант, удалите соответствующий языковой файл или не создавайте его.
Применение изменений
После сохранения client-scripts.js или client-snippets.html обновите страницу в браузере.
После сохранения SSR-файла откройте страницу заново. Frontend проверяет время изменения файла и использует новое содержимое без пересборки и перезапуска службы.
Перезапуск iex-frontend.service требуется только после изменения:
Nginx отправляет пользовательские файлы с заголовками, запрещающими хранение устаревшей копии:
Кеширование собственных файлов стороннего сервиса при этом регулируется самим сторонним сервисом.
Проверка браузерного режима
Проверьте доступность файлов
Выполните:
Ожидается успешный HTTP-ответ и заголовки, запрещающие кеширование.
Успешный ответ по /ng-custom/ подтверждает только доступность файла. Он не подтверждает, что браузерный или SSR-режим включён.
Проверьте runtime-флаг
Откройте сайт, затем инструменты разработчика и вкладку Console.
Выполните:
Ожидаемый результат при включённом браузерном режиме:
Проверьте API
Выполните:
Ожидаемый результат:
Проверьте текущий маршрут:
Проверьте загрузку файлов
Во вкладке Network найдите:
Во вкладке Console проверьте отсутствие сообщений с префиксом:
Проверка SSR-режима
Запросите исходный HTML страницы:
Для страницы с языковым префиксом используйте её фактический адрес:
Также можно открыть в браузере исходный код страницы и найти:
Маркер появляется только для непустого слота.
Изменение применено корректно, если файл доступен по Frontend-домену, нужный режим включён, браузерный API или SSR-маркер присутствует, а интеграция продолжает работать после переходов между страницами.
Безопасность
Пользовательские вставки являются доверенным кодом и не работают в изолированной среде.
JavaScript получает доступ к странице с теми же возможностями, что и основной клиентский код. Он может изменять DOM, читать доступные браузеру данные, отправлять сетевые запросы и влиять на интерфейс обменника.
Соблюдайте следующие правила:
добавляйте код только из доверенного источника;
используйте только HTTPS-адреса внешних ресурсов;
не вставляйте приватные ключи и секретные токены;
не предоставляйте доступ к файлам непроверенным пользователям;
проверяйте код поставщика перед публикацией;
используйте уникальный
idдля внешних скриптов;не отключайте Content Security Policy полностью;
не используйте
chmod 777;не создавайте символические ссылки вместо базовых файлов;
не вставляйте полный HTML-документ;
не используйте
<base>.
Если внешний ресурс блокируется Content Security Policy, разрешите только необходимый домен в соответствующей директиве:
Набор директив зависит от того, какие ресурсы загружает интеграция. Не добавляйте широкие разрешения без необходимости.
Если браузерный код не выполняется
Проверьте значения:
После изменения frontend.env перезапустите Frontend:
Проверьте runtime-флаг в браузере:
Если значение отсутствует или равно false, браузерный режим не включён в HTML текущего процесса Frontend.
Если код работает только после полной загрузки
SSR-скрипты запускаются только при полной загрузке документа.
Для повторной работы после Angular-навигаций перенесите логику в client-scripts.js и используйте:
Не используйте фиксированные задержки в несколько секунд, если достаточно onPageReady().
Если виджет появляется несколько раз
Используйте уникальный id при загрузке:
Для HTML-контейнера используйте mount():
Не создавайте новую подписку на каждом переходе без удаления предыдущей. Сохраните функцию отписки и вызовите её, когда подписка больше не нужна.
Если SSR-маркеры отсутствуют
Проверьте:
значение
CLIENT_CUSTOM_SSR_ENABLED;содержимое соответствующего SSR-файла;
языковой подкаталог текущей страницы;
наличие только комментариев или пробелов;
состояние службы
iex-frontend.service.
После изменения только содержимого SSR-файла перезапуск не требуется.
Если используется неправильный язык
Проверьте наличие файла в каталоге текущего языка.
Помните, что существующий пустой языковой файл останавливает поиск и отключает этот слот. Чтобы использовать общий файл, не создавайте языковую версию или удалите ненужный языковой файл после сохранения резервной копии.
Если файл возвращает 403 или 404
Проверьте точный путь:
Проверьте права всех компонентов пути:
Не используйте:
скрытые имена, начинающиеся с точки;
PHP-подобные расширения;
символические ссылки;
каталог текущего релиза вместо
shared/frontend/ng-custom.
Не добавляйте вручную новый блок Nginx. Конфигурация /ng-custom/ управляется установщиком и может быть восстановлена из шаблона при следующей серверной операции.
Если изменения исчезли после обновления
Штатное обновление сохраняет:
Если изменения исчезли, вероятнее всего редактировался файл внутри активного релиза, например current, releases, dist или public.
Перенесите актуальный код в общий каталог shared/frontend/ng-custom. Не редактируйте собранные файлы Frontend.
Если Frontend не запускается после изменения настроек
Проверьте службу:
Проверьте последние записи журнала:
Проверьте синтаксис и значения в:
Убедитесь, что CLIENT_CUSTOM_DIR содержит абсолютный штатный путь:
Отключение пользовательских вставок
Откройте:
Для полного отключения установите:
Перезапустите Frontend:
Отключение режима не удаляет содержимое файлов.
Даже при выключенных режимах статические файлы могут оставаться доступными напрямую через /ng-custom/. Если в файл случайно попал секрет, немедленно удалите его из публичного каталога и отзовите или замените сам секрет.
Откат содержимого
Для отката верните предыдущую проверенную версию соответствующего файла в:
После восстановления HTML, CSS или JavaScript перезапуск Frontend не требуется.
Проверьте:
После этого повторите проверку в браузере на первой странице, при переходе между разделами и в личном кабинете.
Последнее обновление
Это было полезно?