How To Rewrite URLs In NGINX Proxy Response?

Published September 4, 2024

Problem: Rewriting URLs in NGINX Proxy Responses

Rewriting URLs in NGINX proxy responses is often needed to change links or resource paths before they reach the client. This task can be complex, especially when working with dynamic content or multiple backend servers. Proper URL rewriting helps links and resources work correctly for end-users, even when the internal structure of the web application is different from its public-facing URLs.

Solution: Configuring NGINX for URL Rewriting

Modifying the NGINX Server Block

To address the URL rewriting issue in NGINX, you need to change the server block configuration. The main task is to adjust the proxy_pass directive.

The proxy_pass directive sets how NGINX forwards requests to the backend server. When using proxy_pass with a URI (including a trailing slash), NGINX replaces the location matching part of the URI with the specified URI. Without a trailing slash, NGINX passes the full original request URI to the backend server.

For your case, remove the trailing slash from the proxy_pass directive:

location /admin/ {
    proxy_pass http://localhost:8080;
}

This setup will keep the /admin/ prefix when forwarding requests to the Tomcat server.

Tip: Test Configuration Changes

After making changes to your NGINX configuration, always test the syntax and reload the server:

nginx -t
nginx -s reload

This helps catch any configuration errors before they affect your live server.

Using sub_filter for HTML Content Rewriting

While changing the proxy_pass directive helps with request forwarding, it doesn't change the content of the responses. To rewrite URLs within the HTML content returned by the backend server, use the sub_filter directive.

The sub_filter directive lets you replace specific strings in the response body. Here's how to use it:

location /admin/ {
    proxy_pass http://localhost:8080;
    sub_filter "http://localhost:8080/" "http://localhost/admin/";
    sub_filter_once off;
}

This setup replaces all occurrences of "http://localhost:8080/"; with "http://localhost/admin/"; in the response body. The sub_filter_once off directive makes sure that all instances of the string are replaced, not just the first one.