How do I redirect all my hrefs
within my response to hit my new path. For e.g., my ingress file is
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-odin
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /odin/?(.*)
backend:
serviceName: flask-app-tutorial
servicePort: 8080
When I visit the page at https://mysite/odin. It works and returns back the response:
The HTML response is:
<html>
..
<body>
<div>
<a href="/v0/index">Home</a>
<a href="/v0/login">Login</a>
</div>
</body>
</html>
However, as you can see, the relative links are like <a href="/v0/index">Home</a>
. If I click on that, it won't work since there is no link like http://mysite/v0/index
. If I click on the link, I want it to go to http://mysite/odin/v0/index
. Is it possible either by modifying the links in the response to have odin
or if I do click on it, it looks at the source url i.e. http://mysite/odin
and direct it relative to that?
Nginx Version: 1.15.10
ingress-nginx: 0.24.0
So far,I have tried the following.
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Accept-Encoding ""; #disable compression
sub_filter '<head>' '<head> <base href="/odin/">';
nginx.ingress.kubernetes.io/add-base-url: ":true"
nginx.ingress.kubernetes.io/app-root: /odin
nginx.ingress.kubernetes.io/use-regex: "true"
I have also tried this i.e.
change the spec.rules.host.paths.path from /odin/?(.*) to/(odin/.*)
There may be a typo in the advice above. I think it should http
instead of host
.
I had a similar problem and inspired by your question I found a solution which worked for me. Your annotation should work like this:
nginx.ingress.kubernetes.io/configuration-snippet: |
sub_filter_once on;
sub_filter '<base href="/"' '<base href="/odin/"';
As you see sub_filter is now enabled and I used base instead of head.
Even if you fix the the sub_filter
configuration snippet by including sub_filter_once on;
as suggested in the other answer it will not work, because the base
tag works only with relative paths (see: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base).
The app-root
solution is technically correct, but boils down to the same thing as <base href=... />
, and thus also will fail for href
tags with a leading slash.
I can see two possibilities:
1) You can fix all your href
tags, removing leading slashes. If you do that both solutions should work.
2) You can try to change your location rule to - path: /(odin)?/?(.*)
and the rewrite annotation to: nginx.ingress.kubernetes.io/rewrite-target: /$2
(not forgetting to include the nginx.ingress.kubernetes.io/use-regex: "true"
annotation as well) and it will work with a leading slash as well.
It looks fragile though, as the rule will now match (almost) anything and you loose the possibility to fan out with NGINX with different path prefixes.
A modification of "2)" to make it a more viable alternative would be to match the /v0
prefix if it's consistent among href
tags, instead of basically anything.