Using try_files while forcing a trailing-slash in the URL
Francis Daly
francis at daoine.org
Tue Jun 18 21:55:00 UTC 2013
On Tue, Jun 18, 2013 at 03:22:04PM -0400, Ben Johnson wrote:
Hi there,
> The try_files directive is brilliant. The only problem I'm having is
> that I would like to be able to force a trailing-slash, a la "rewrite",
> on the fallback URL.
> This works well, but I have a need to eliminate duplicate URLs (for SEO
> ["duplicate-content penalty"] reasons) by forcing a trailing slash on
> all virtual URLs (that is, URLs that do not point to a real file or
> directory).
>
> Am I missing something obvious?
try_files decides which file to serve, with a single fallback option. If
that fallback option is something complicated, it is probably best to
use a named location and put the complications in there.
> I was able to cook-up a "working solution", but it will probably bristle
> a few peoples' hair:
If it works, it works. If you can measure the load on your test server,
you may be interested in trying other things too and comparing.
For example:
location / {
try_files $uri $uri/ @virtual;
}
location @virtual {
if ($uri !~ '/$') {
return 301 $uri/$is_args$args;
}
fastcgi_pass unix:php.sock;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include fastcgi_params;
}
as well as a location for handling /index.php or any similar things
directly.
(Depending on what exactly your php script does, you may also want to
set QUERY_STRING explicitly.)
> Ultimately, I'm wondering if there's a means by which to achieve the
> above with try_files, and if not, if there's a better means than what
> I've employed on my own.
The above uses try_files, and uses "if" within "location" with only
"return", which is a safe thing to do. http://wiki.nginx.org/IfIsEvil
> A related "problem" (more an inconvenience, really) is that using
> try_files in the manner described in the cited documentation causes the
> trailing ampersand ("&") to be appended to "q" even when there are no
> $args. Is this behavior intentional? Maybe there's an RFC of which I"m
> unaware that lead to this decision.
You asked for $uri, then &, then $args.
You should be surprised if you get anything other than $uri, then &,
then $args.
I suspect it was done because the php script it feeds is known to ignore
the unnecessary &.
nginx does provide the variable $is_args, but that is intended for other
circumstances where it is more useful. You could do more "if" things on
$is_args or on $args to decide whether to add the &, if you want to.
Good luck with it,
f
--
Francis Daly francis at daoine.org
More information about the nginx
mailing list