Canonical URLs with Nginx
We're working on removing the directory index files from our URLs to clean things up and provide more consistency to improve our SEO.
However, I'm not familiar with how to take care of this in Nginx.
I found the following for Apache (we're just looking for the Nginx equivalent)
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.php\ HTTP/
RewriteRule ^(([^/]+/)*)index\.php$ http://www.%{HTTP_HOST}/ [R=301开发者_运维知识库,NS,L]
I've read the docs and tried several different options - the closest I can get will still return an infinite loop error.
The snippet you posted for Apache uses the immutable global variable %{THE_REQUEST}
to determine the original URI requested by the client. However, this variable contains the entire request, including the HTTP method, version, and query string. Therefore, parsing this variable is a bit messy, as seen in the example you posted.
However, nginx
has a dedicated variable that holds the original request URI received from the client: $request_uri
. This allows you to do the following:
## REDIRECT foo/index(.html) to foo/
if ($request_uri ~ ^(.*/)index(?:\.html)?$) {
return 301 $1;
}
If you wanted to also strip the file suffix, e.g. .html
, you could use the following snippet:
## REDIRECT foo/bar.html to foo/bar
if ($request_uri ~ ^(.+)\.html$) {
return 301 $1;
}
Now, in order for nginx
to still be able to serve the correct file, one uses the try_files
directive, which checks all given URIs in sequence until one matches:
## Rewrite internal requests for foo/bar to foo/bar.html
try_files $uri $uri.html =404;
So a request for /foo/bar
would be handled as follows:
- return
$uri
=/foo/bar
, if that file exists in the document root, otherwise - return
$uri.html
=/foo/bar.html
if it exists, finally - issue a 404 error.
精彩评论