Предположим, что у меня есть доменное имя xxx.yyy.com, но я не владею ни одним из его поддоменов (*.xxx.yyy.com).
Поэтому я должен направить каждый HTTP-запрос на соответствующий сервис с помощью path
. Например, перенаправление xxx.yyy.com/app1/ на сервис app1
и xxx.yyy.com/app2/ на сервис app2
.
Я настраиваю свои ресурсы kubernestes, как показано ниже:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: xxx.yyy.com
http:
paths:
- pathType: Prefix
path: "/app1"
backend:
service:
name: app1
port:
number: 8000
- pathType: Prefix
path: "/app2"
backend:
service:
name: app2
port:
number: 8000
---
apiVersion: v1
kind: Service
metadata:
name: app1
spec:
selector:
app: app1
ports:
- protocol: TCP
port: 8000
---
apiVersion: v1
kind: Service
metadata:
name: app2
spec:
selector:
app: app2
ports:
- protocol: TCP
port: 8000
Это работает в большинстве случаев, за исключением передних веб-приложений.
В коде HTML и javascript внешнего веб-приложения мы ссылаемся на его ресурсы (изображения, HTTP API) на внутреннем сервере по корневому пути ("/") , как если бы оно было развернуто на собственном сервере.
Например, в javascript-коде app1
мы вызываем fetch('/api/getUsers')
вместо fetch('/app1/api/getUsers')
, поэтому вход не смог направить /api/getUsers
на сервис app1
.
Я знаю, что это можно легко решить, перенаправив запрос host
, а не path
. Но у меня нет разрешения на создание поддоменов.
Итак, как можно решить этот сценарий фронтальных веб-приложений с помощью маршрутизации через path
ingress?
Когда веб-приложение доступно для браузера по определенному пути, клиентские запросы должны быть нацелены на этот путь. Вы можете достичь этого,
api/guestUsers
вместо /api/guestUsers
/app1/img/logo.png
.Второй способ поддерживается, например:
publicPath: "/app1"
<BrowserRouter basename = "/app1"/>
<base href = "/app1"/>
Этот параметр может быть динамически заполнен серверной переменной или даже установить автоматически в местоположении точки входа.
Скажем, оба приложения app1 и app2 получают /logo.png
и отображают его. Вы можете разместить одно приложение в /app1/...
, а другое — в /app2/...
, но один логотип, который вы предоставите в /logo.png
, будет отображаться в обоих приложениях. Хорошо, вы можете сделать маршрутизация на основе заголовка Referer
, но это, вероятно, приведет к странным побочным эффектам, по крайней мере, с кэшированием.
Подход Referer звучит хорошо! Почему это может привести к побочным эффектам кэширования?
Для меня это больше похоже на забавный академический эксперимент. В любом случае, когда http://xxx.yyy/logo.png
возвращает другой контент на основе заголовка запроса Referer
, браузер может кэшировать его, поэтому вы увидите неправильный логотип в /app2/
при посещении /app1
ранее. Вы можете отключить это поведение, установив заголовок ответа no-cache
, но таким образом вы потеряете кеширование. Не рекомендовал бы.
В вашем приложении используйте window.location.href
и проанализируйте первую часть URL-адреса и используйте ее в качестве основы для ваших запросов.
const url = new URL(window.location.href);
const appName = url.pathname.split('/').length > 2 ? url.pathname.split('/')[1] : "";
const baseApiUrl = new URL(appName, url).toString();
fetch(baseApiUrl + '/api/getUsers')
.then((res) = {})
.catch((error) => { console.info(error)})
Благодарю. но у меня нет внешнего веб-приложения. есть ли способ не изменять код внешнего веб-приложения, только изменяя код конфигурации kubernetes или nginx?