Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NGINX, proxy_pass and SPA routing in HTML5 mode

I have NGINX set up as a reverse proxy for a virtual network of docker containers running itself as a container. One of these containers serves an Angular 4 based SPA with client-side routing in HTML5 mode.

The application is mapped to location / on NGINX, so that http://server/ brings you to the SPA home screen.

server {
    listen 80;

    ...

    location / {
        proxy_pass http://spa-server/;
    }

    location /other/ {
        proxy_pass http://other/;
    }

    ...
}

The Angular router changes the URL to http://server/home or other routes when navigating within the SPA.

However, when I try to access these URLs directly, a 404 is returned. This error originates from the spa-server, because it obviously does not have any content for these routes.

The examples I found for configuring NGINX to support this scenario always assume that the SPA's static content is served directly from NGINX and thus try_files is a viable option.

How is it possible to forward any unknown URLs to the SPA so that it can handle them itself?

like image 845
Martin Klinke Avatar asked Aug 04 '17 08:08

Martin Klinke


People also ask

What does proxy_pass to Nginx?

The proxy_pass setting makes the Nginx reverse proxy setup work. The proxy_pass is configured in the location section of any virtual host configuration file. To set up an Nginx proxy_pass globally, edit the default file in Nginx's sites-available folder.

Why use Nginx reverse proxy?

Security and anonymity – By intercepting requests headed for your backend servers, a reverse proxy server protects their identities and acts as an additional defense against security attacks.

How do you check if Nginx reverse proxy is working?

To check the status of Nginx, run systemctl status nginx . This command generates some useful information. As this screenshot shows, Nginx is in active (running) status, and the process ID of the Nginx instance is 8539.


1 Answers

The solution that works for me is to add the directives proxy_intercept_errors and error_page to the location / in NGINX:

server {
    listen 80;

    ...

    location / {
        proxy_pass http://spa-server/;
        proxy_intercept_errors on;
        error_page 404 = /index.html;
    }

    location /other/ {
        proxy_pass http://other/;
    }

    ...
}

Now, NGINX will return the /index.html i.e. the SPA from the spa-server whenever an unknown URL is requested. Still, the URL is available to Angular and the router will immediately resolve it within the SPA.

Of course, now the SPA is responsible for handling "real" 404s. Fortunately, this is not a problem and a good practice within the SPA anyway.

UPDATE: Thanks to @dan

like image 197
Martin Klinke Avatar answered Oct 18 '22 19:10

Martin Klinke