Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
486 views
in Technique[技术] by (71.8m points)

angular - Nginx reverse proxy with dynamic basehref?

I have built an i18n app with Angular 9. My api is proxied with the /api/ url. But since i added i18n, proxy doesnt work anymore. Rq: (Angular add /fr/ or /en/ to the url because i add --baseHref flag on compilation)

I want to know how can i tell to my proxy to add the dynamic basehref of my app to the proxy url ? Exemple : How to transform GET myapp.com/fr/api/jobs to GET myapp.com/api/jobs ?

So i have this nginx configuration :

location /fr/ { 
      autoindex on;
      try_files $uri$args $uri$args/ /fr/index.html;
  }

  location /en/ {
      autoindex on;
      try_files $uri$args $uri$args/ /en/index.html;
  }

  # Default to FR
  location / {
      # Autoindex is disabled here + the $uri$args/ is missing from try_files
      try_files $uri$args /fr/index.html;
  }

# Proxy to API call
  location */api/ {
    proxy_pass http://rest-api:9000;
  }

I'm trying to listen everythin before /api/ but this doesnt work...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Consider this location:

  location ~ .*/api/(.*) {
    proxy_pass http://rest-api:9000/api/$1;
  }

This is a regex location that match any URI with /api/ anywhere in it. For example it will work on:

example.com/api/foo/bar
example.com/api/
example.com/something/api/foo/bar

There is a capture group (.*) to record whatever was after /api/. It is saved as a positional variable $1 (because it's the first and only capture group in the expression). Using it you can build an exact path to your API backend:

proxy_pass http://rest-api:9000/api/$1;

It will turn the examples above into:

proxy_pass http://rest-api:9000/api/foo/bar
proxy_pass http://rest-api:9000/api/
proxy_pass http://rest-api:9000/api/foo/bar

Update: When you use a regex variable $1 in proxy_pass you have to build full URL manually. If your URL can contain arguments (like ?foo=bar) you need to add $is_args$args. '$is_args' is responsible for adding ? if there are any arguments and '$args' are the actual arguments. The full path will be like this:

proxy_pass http://rest-api:9000/api/$1$is_args$args

Bonus: you can use this simple server to see how NGINX will interpret the configuration:

server {
  listen 8080;
  location ~ .*/api/(.*) {
    add_header Content-Type text/plain;
    return 200 http://api-server:9000/api/$1;
  }
}

Access any path with /api/ in it and you will see in your browser how your current location is interpreted.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share

2.1m questions

2.1m answers

63 comments

56.6k users

...