Why nginx "return 301" and ”try_files“ fall into an infinite loop

my conf code:

index index.html index.php;
location / {
    if ($uri = '/a/') {
        return 301 https://example.com/a;
    }
    try_files $uri $uri/ =404; 
}

If url is /a/, 301 to /a, then try_files part, add / to /a end, become /a/.

Next step, I think it will try the index definition, become /a/index.html, and reach the file.

But actually, It tried /a/, and jump out the location, then goes into location again, to if ($uri = '/a/') { ... }.

Then an infinite loop.

Why, I just got confused.


What I want to do is

  1. If request example.com/a/, jump to example.com/a, then to 2
  2. If request example.com/a, show example.com/a/index.html (but url is example.com/a).

Anyone can help me to reach this?


Solution 1:

It's doing exactly what it's meant to do.

You can never reach /a/index.html because you keep redirecting back to /a before this can possibly happen. When nginx processes this, it sees the directory on the filesystem and automatically redirects (correctly) to /a/.

You should remove this inappropriate redirect.