1

Suppose I own a domain name xxx.yyy.com, but I doesn't own any subdomain name (*.xxx.yyy.com) of it.

So I have to route each HTTP request to its corresponding service by path. For example, routing xxx.yyy.com/app1/ to service app1 and xxx.yyy.com/app2/ to service app2.

I config my kubernestes resources as below:

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

This works in most of the cases, except in front webapps.

In a front webapp's HTML and javascript code, we refer its assets (images, HTTP APIs) on the backend server by root path ("/") , as if it is deployed on its own server.

For example in the javascript code of app1 , we call fetch('/api/getUsers') instead of fetch('/app1/api/getUsers'), so the ingress failed to route /api/getUsers to service app1.

I know it can be solved easily by routing request by host not by path. But I don't have the permission to create subdomains.

So how can this scenario of front webapps be solved by routing by path ingress?

benjaminchanming
  • 538
  • 5
  • 17

2 Answers2

1

When the Web application is available to the Browser beneath a certain path, the front end requests need to target that path. You can achieve this by

  • using only relative path names like api/guestUsers instead of /api/guestUsers
  • or prefixing every query url with that path, like /app1/img/logo.png.

The second way is supported by, for example by:

This setting could be dynamicly filled with a server variable or even set automatically to the location of the entry point.

Knight Industries
  • 1,325
  • 10
  • 20
  • thanks. but I don't own the frontend web app. is there any way not by changing the frontend web app code, only changing kubernetes or nginx config code? – benjaminchanming Apr 08 '22 at 03:14
  • Say both app1 and app2 fetch a `/logo.png` and display it. You could serve one app at `/app1/...` and the other at`/app2/...` but the one logo you provide at `/logo.png` will show up in both apps. Ok, you could do the [routing based on the `Referer` header](https://stackoverflow.com/questions/53718930/conditional-routing-with-nginx-based-on-referer) but this would probably result in strange side effects at least with caching. – Knight Industries Apr 08 '22 at 05:29
  • The Referer approach sounds good! Why it would result in caching side effects? – benjaminchanming Apr 08 '22 at 12:39
  • It sounds more like a fun academic experiment to me. Anyways, when `http://xxx.yyy/logo.png` returns different content based on the `Referer` request header, the browser could cache it so you would see the wrong logo in `/app2/` when you visited `/app1` before. You could disable this behaviour by setting a [`no-cache`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) response header, but you would lose caching this way. Would not recommend. – Knight Industries Apr 08 '22 at 14:03
0

In your application use window.location.href and parse the first part of the URL and use it as base for your requestes.

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.log(error)})
harry
  • 672
  • 3
  • 13