Ingress-nginx: Angular URL Rewrite

Created on 2 Jul 2019  路  12Comments  路  Source: kubernetes/ingress-nginx

Is this a request for help? (If yes, you should use our troubleshooting guide and community support channels, see https://kubernetes.io/docs/tasks/debug-application-cluster/troubleshooting/.):

Yes

What keywords did you search in NGINX Ingress controller issues before filing this one? (If you have found any duplicates, you should instead reply there.):

URL rewrite?


Is this a BUG REPORT or FEATURE REQUEST? (choose one):

NGINX Ingress controller version: 0.24.1

Kubernetes version (use kubectl version): v1.13.5

Environment: AKS

  • Cloud provider or hardware configuration: AKS
  • OS (e.g. from /etc/os-release):
  • Kernel (e.g. uname -a):
  • Install tools:
  • Others:

What happened:

Angular application:

`apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
namespace: ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
spec:
tls:

  • hosts:

    • dev.dev.com

      secretName: cert

      rules:

  • host: dev.dev.com
    http:
    paths:

    • path: /merchant(/|$)(.*)

      backend:

      serviceName: service

      servicePort: 80`

Calling the url dev.dev.com/merchant shows a blank page. In console, it says:

GET https://dev.dev.com/runtime.js net::ERR_ABORTED 404

What you expected to happen:
It should be loading resources from

htts://dev.dev.com/merchant/runtime.js

To make it work. (Can confirm if accessing that URL directly it will load the JS and other resources that's 404-ing)

Any resources from the deployment should stay in the /merchant/* rather than load at /

How to reproduce it (as minimally and precisely as possible):

Anything else we need to know:

lifecyclrotten

Most helpful comment

Request comes in for https://dev.dev.com/merchant -> matches the location generated with no match for the second capture group ($2) in the rewrite, so the request hits your service at / -> service (presumably) responds with an index.html file -> html file presumably has a tag that looks something like <script src="runtime.js" />.

But since the URL is still https://dev.dev.com/merchant, the relative path in the script src isn't appended to merchant, as merchant isn't a directory, so it looks for runtime.js in the current "directory", i.e. /. If you instead navigate to https://dev.dev.com/merchant/ I suspect you'll get the behavior you'd expect (this SO answer explains that)

The simple solution theoretically is to respond with a 301 with the trailing slash tacked on the end when the request is for just /merchant. In the past I'd gotten around this by adding a configuration snippet annotation that sends the 301 with the trailing slash when the request is for the location and nothing more.

nginx.ingress.kubernetes.io/configuration-snippet: |
if ($uri = "/merchant") {rewrite .* $1/ permanent;}

That should work, but if you continue adding more paths with more services, it not exactly scalable. I've used logic similar to that in the past by using $baseuri to programmatically determine when the trailing slash needs to be added, but it was removed in 0.22.0.

All 12 comments

htts://dev.dev.com/merchant/runtime.js

That's not how it works. NGINX can only rewrite the incoming traffic, changing the URL to the backend, it doesn't change the response from your application.

I am having the same issue and I don't see how this could be an issue of the application.

Request comes in for https://dev.dev.com/merchant -> matches the location generated with no match for the second capture group ($2) in the rewrite, so the request hits your service at / -> service (presumably) responds with an index.html file -> html file presumably has a tag that looks something like <script src="runtime.js" />.

But since the URL is still https://dev.dev.com/merchant, the relative path in the script src isn't appended to merchant, as merchant isn't a directory, so it looks for runtime.js in the current "directory", i.e. /. If you instead navigate to https://dev.dev.com/merchant/ I suspect you'll get the behavior you'd expect (this SO answer explains that)

The simple solution theoretically is to respond with a 301 with the trailing slash tacked on the end when the request is for just /merchant. In the past I'd gotten around this by adding a configuration snippet annotation that sends the 301 with the trailing slash when the request is for the location and nothing more.

nginx.ingress.kubernetes.io/configuration-snippet: |
if ($uri = "/merchant") {rewrite .* $1/ permanent;}

That should work, but if you continue adding more paths with more services, it not exactly scalable. I've used logic similar to that in the past by using $baseuri to programmatically determine when the trailing slash needs to be added, but it was removed in 0.22.0.

hi @gbhmt , the static network calls still goes to / only even after adding the configuration-snippet.
image

Am I missing something?

please disregard, the tag we were using was the problem. sorry

please disregard, the tag we were using was the problem. sorry

what do you mean? I'm having exactly the same problem.

Which tag are you talking about. Even I am still facing the problem.

@sindrunas so my app is hosted with a prefix, e.g. http://foo/myapp. I needed to set the base-href in angular to /myapp and then it worked as expected

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle rotten

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close

@fejta-bot: Closing this issue.

In response to this:

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

whereisaaron picture whereisaaron  路  3Comments

yuyang0 picture yuyang0  路  3Comments

cehoffman picture cehoffman  路  3Comments

sophaskins picture sophaskins  路  3Comments

kfox1111 picture kfox1111  路  3Comments