docs(article): добавлен раздел про base href и deploy-url для /ui/simple и рекомендации по SPA-фоллбэку

This commit is contained in:
2025-09-11 16:56:59 +06:00
parent 2012fb3afc
commit f94bba14a1

View File

@@ -7,7 +7,7 @@ date: 2025-09-10 18:00
author: Direct-Dev (aka Антон Кузнецов) author: Direct-Dev (aka Антон Кузнецов)
level: Средний level: Средний
tags: #go #angular #spa #embed #static #cli #webui #devops tags: #go #angular #spa #embed #static #cli #webui #devops
version: 1.0.1 version: 1.0.2
``` ```
## Содержание ## Содержание
@@ -23,6 +23,7 @@ version: 1.0.1
- [Встраивание в Go-сервис](#встраивание-в-go-сервис) - [Встраивание в Go-сервис](#встраивание-в-go-сервис)
- [API: контракт и примеры](#api-контракт-и-примеры) - [API: контракт и примеры](#api-контракт-и-примеры)
- [Запуск и проверка](#запуск-и-проверка) - [Запуск и проверка](#запуск-и-проверка)
- [SPA под произвольным префиксом (/ui/simple): base href и deploy-url](#spa-под-произвольным-префиксом-uisimple-base-href-и-deploy-url)
- [FAQ и типичные ошибки](#faq-и-типичные-ошибки) - [FAQ и типичные ошибки](#faq-и-типичные-ошибки)
## Введение ## Введение
@@ -133,13 +134,13 @@ knock-gui/
## Минимальный GUI ## Минимальный GUI
Оставили только то, что реально нужно для «пнул порт — и поехали». Поля формы и кнопка запуска — никаких лишних переключателей. Оставил только то, что реально нужно для «пнул порты». В main полный интерфейс ...
Ключевой шаблон компонента: Ключевой шаблон компонента:
```12:60:/home/su/projects/articles/embed-gui-article/ui/src/app/knock/knock-page.component.html ```12:60:/home/su/projects/articles/embed-gui-article/ui/src/app/knock/knock-page.component.html
<div class="container"> <div class="container">
<p-card header="Port Knocker (Минимальный UI)"> <p-card header="Port Knocker (Minimal UI)">
<form [formGroup]="form" (ngSubmit)="execute()" class="p-fluid"> <form [formGroup]="form" (ngSubmit)="execute()" class="p-fluid">
<div class="grid"> <div class="grid">
<div class="col-12"> <div class="col-12">
@@ -163,7 +164,7 @@ knock-gui/
</div> </div>
``` ```
Логика отправки запроса — проста как три рубля: Логика отправки запроса:
```1:40:/home/su/projects/articles/embed-gui-article/ui/src/app/knock/knock-page.component.ts ```1:40:/home/su/projects/articles/embed-gui-article/ui/src/app/knock/knock-page.component.ts
this.http.post('/api/v1/knock-actions/execute', { this.http.post('/api/v1/knock-actions/execute', {
@@ -173,6 +174,8 @@ this.http.post('/api/v1/knock-actions/execute', {
}).subscribe(...) }).subscribe(...)
``` ```
> ну да, ну да надо сервис и все такое ...
Так как страницы GUI защищены BasicAuth, браузер после ввода пароля сам будет добавлять заголовок Authorization и к XHRзапросам — отдельно в коде его прокидывать не нужно. Так как страницы GUI защищены BasicAuth, браузер после ввода пароля сам будет добавлять заголовок Authorization и к XHRзапросам — отдельно в коде его прокидывать не нужно.
## Сборка фронтенда ## Сборка фронтенда
@@ -268,6 +271,59 @@ http://localhost:8888
Если что-то не так — загляните в логи терминала и сетевую вкладку DevTools. Если что-то не так — загляните в логи терминала и сетевую вкладку DevTools.
## SPA под произвольным префиксом (/ui/simple): base href и deploy-url
Иногда нужно отдавать SPA не с корня `/`, а, скажем, по пути `/ui/simple`. Для Angular это значит две вещи: правильный `<base href>` в `index.html` и корректные пути к ассетам.
Вариант A: собрать с заданным base-href и deploy-url:
```bash
# пример сборки под префикс /ui/simple
npx ng build --configuration production \
--base-href /ui/simple/ \
--deploy-url /ui/simple/
```
Что это даёт:
- В `dist/.../browser/index.html` будет `<base href="/ui/simple/">`.
- Все ссылки на бандлы/ассеты будут начинаться с `/ui/simple/`.
Вариант B: поправить `index.html` вручную после сборки (минимальный вариант):
```html
<!-- ui/dist/project-front/browser/index.html -->
<base href="/ui/simple/">
```
Важно: закрывающий слеш обязателен, иначе роутинг может «ехать».
Настройка бэкенда:
- Сервируйте содержимое собранной папки по маршруту `/ui/simple` (или скопируйте артефакты в `back/cmd/public/ui/simple/`).
- SPAфоллбэк должен отдавать `index.html` при запросах внутри префикса, если это не файловые ресурсы.
Если у вас универсальный обработчик (как в `setupStaticRoutes`) на корне, два простых подхода:
- Хранить файлы в `public/ui/simple/...` — тогда запросы к `/ui/simple/...` будут удовлетворены корректно.
- Либо сделать отдельный хендлер, который для путей с префиксом `/ui/simple` читает файлы из подкаталога, а на несуществующие файлы отвечает содержимым `public/ui/simple/index.html`.
Пример маппинга структуры в `public/`:
```text
public/
├── ui/
│ └── simple/
│ ├── index.html # с <base href="/ui/simple/">
│ ├── main-*.js
│ ├── styles-*.css
│ └── assets/...
└── ...
```
Проверка:
```text
http://localhost:8888/ui/simple
```
Если при прямом заходе на вложенный роут `/ui/simple/some/child` видите 404 — значит фоллбэк не отрабатывает. Проверьте, что при отсутствии файла по этому пути сервер возвращает `public/ui/simple/index.html`.
## FAQ и типичные ошибки ## FAQ и типичные ошибки
- «Сервер ругается на пароль»: не задали `GO_KNOCKER_SERVE_PASS` или запустили в другой сессии. Экспортните переменную и перезапустите. - «Сервер ругается на пароль»: не задали `GO_KNOCKER_SERVE_PASS` или запустили в другой сессии. Экспортните переменную и перезапустите.