开发者

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:

  1. return $uri = /foo/bar, if that file exists in the document root, otherwise
  2. return $uri.html = /foo/bar.html if it exists, finally
  3. issue a 404 error.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜