Redirect / foo.html in / foo, but not / to / index in nginx

My files on disk have extensions: index.html , a.html . I want the request http://example.com/a download /var/www/a.html and http://example.com/ to download /var/www/index.html . I want any other URL to be redirected to the canonical URL, so http://example.com/a.html should be redirected to http://example.com/a .

My configuration looks like this:

 rewrite ^(/.+)\.html$ $scheme://$host$1 permanent; location / { root /var/www; try_files $uri.html $uri $uri/ =404; } 

This redirects /a.html to /a and a.html when loading a.html from disk:

 $ curl -D- -s http://www.jefftk.com/food.html | grep ^Location Location: http://www.jefftk.com/food $ curl -s http://www.jefftk.com/food | grep ^Location 

But it sends / to /index :

 $ curl -s -D- http://www.jefftk.com/pictures/ | grep ^Location Location: http://www.jefftk.com/pictures/index $ curl -s -D- http://www.jefftk.com | grep ^Location Location: http://www.jefftk.com/index 

If I delete the rewrite rule, it stops redirecting from /a.html to /a , but also stops sending / to /index to /index :

 $ curl -D- -s http://www.jefftk.com/food.html | grep ^Location $ curl -D- -s http://www.jefftk.com/food | grep ^Location $ curl -D- -s http://www.jefftk.com/ | grep ^Location $ curl -D- -s http://www.jefftk.com/pictures/ | grep ^Location 

Why is this going to happen? Can I do nginx for both things I want (extension .html , no index in url) at the same time?

+6
source share
2 answers

I think your rewrite rule might be reversed. Maybe just this (no rewrite rule):

 location / { try_files $uri.html $uri $uri/ =404; } location = / { index index.html; } 

UNITED VERSION:

Sorry, I did not understand your description completely. I re-read it several times and checked this, and it may be closed by what you want to do:

 location = / { try_files /index.html =404; } location = /index { return 301 $scheme://$host; } location ~* \.html$ { rewrite ^(.+)\.html$ $scheme://$host$1 permanent; } location / { try_files $uri.html $uri/ @backend; } location @backend { # rewrite or do whatever is default for your setup rewrite ^ /index.html last; // or return 404; } 

CODE EXAMPLE (REVISION 3):

I hope this is the third time it's a charm. Perhaps this will solve your problem?

 # example.com/index gets redirected to example.com/ location ~* ^(.*)/index$ { return 301 $scheme://$host$1/; } # example.com/foo/ loads example.com/foo/index.html location ~* ^(.*)/$ { try_files $1/index.html @backend; } # example.com/a.html gets redirected to example.com/a location ~* \.html$ { rewrite ^(.+)\.html$ $scheme://$host$1 permanent; } # anything else not processed by the above rules: # * example.com/a will load example.com/a.html # * or if that fails, example.com/a/index.html location / { try_files $uri.html $uri/index.html @backend; } # default handler # * return error or redirect to base index.html page, etc. location @backend { return 404; } 
+1
source

You are looking for something like this:

 location / { try_files $uri.html $uri/index.html =404; } 

Basically, try a.html file a.html , if that fails, it will try index.html and in the latter case it will show a 404 . Also, please remember restart nginx after editing the vhost file.

0
source

All Articles