Nginx redirect to url with slash at end, from all urls with few exceptions

nginxweb-server

I need to redirect all url (with several exceptions) to url with slash on end.
Like https://example.org/some-url => https://example.org/some-url/

But I want to prevent redirect, if this is:

  • file
  • directory
  • one of exception urls
  • one of wildcard urls, that
    return file from 'style.css', 'style.123.css', 'style.34553.css'

I used following config to redirect to urls with slashes at the end:

set $my_var 0;
if (-f $request_filename) {
  set $my_var 1;
}
if (-d $request_filename) {
  set $my_var 1;
}
if ($request_uri ~ "^.*/market/cart$") {
  set $my_var 1;
}
if ($request_uri ~ "^.*/market/order/accept$") {
  set $my_var 1;
}
if ($request_uri ~ "^.*/market/order/status$") {
  set $my_var 1;
}
if ($my_var = 0) {
  rewrite ^(.*[^/])$ $1/ permanent;
}

to create wildcard redirects, i used

location ~* (.+)\.(?:\d+)\.(js|css|png|jpg|jpeg|gif)$ {
  try_files $uri $1.$2;
}

But how can I use redirects to slashes at end with this wildcard location?
Maybe here is the way to make this config more right and clear.

Best Answer

I have not tested this myself, so it might not work. But you can try this:

location / {
    try_files $uri @addslash =404;
}

location @addslash {
    rewrite ^(.+[^/])$ $1/ permanent;
}

location ~ /market/cart$ {
    ... your try_files statement from configuration
}

location ~ /market/order/(?:accept|status)$ {
    ... your try_files statement from configuration
}

location ~* (.+)\.(?:\d+)\.(js|css|png|jpg|jpeg|gif)$ {
    try_files $uri $1.$2;
}

We use the @addslash location block for adding the slash to the URLs.

Then we use separate location blocks for the URLs you want to process without adding slash to end. I simplified and combined the regex patterns a bit. Here you need to copy your CMS front controller pattern try_files statement so that the requests are correctly passed to your CMS.

Finally we have the regex for matching images.

This should give you the behaviour you are looking for, because of the order nginx processes location blocks.