可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to redirect URLs without slash to the path with trailing slash. So /some-url to /some-url/
And the rest of the URLs, like
- /some-url.xml
- /some-url?
- /some-url?q=v
- /some-url/
Should stay without redirection.
I found this article https://www.ateamsystems.com/tech-blog/nginx-add-trailing-slash-with-301-redirect-without-if-statements/ in which author suggests to use following rule:
location ~ ^([^.\?]*[^/])$ { try_files $uri @addslash; } location @addslash { return 301 $uri/; }
Unfortunately this doesn't really work. Because url /some-url?q=v gets redirected to /some-url/
Could you suggest how to change regular expression to make it work?
回答1:
This should solve the problem:
location / { if ($request_uri ~ ^([^.\?]*[^/])$) { return 301 $1/; } try_files $uri $uri/ /index.php$is_args$args; }
回答2:
The query string begins at the ?
and is not part of the normalized URI used when matching location
and rewrite
directives. The entire URI is available as the $request_uri
variable. You could use your regular expression within an if
block:
if ($request_uri ~ ^([^.?]*[^/])$ ) { return 301 $1/; }
See this document for more, and this caution on the use of if
.
回答3:
I figured out how to do this without an if statement! This solves all the problems you mentioned (except case #2, and in case #3 it redirects but retains the query string).
# 301 try_file for trailing slash location ~ ^([^.\?]*[^/])$ { try_files $uri @addslash; } # 301 redirect for trailing slash location @addslash { return 301 $uri/$is_args$args; } # Root directory location handler location / { try_files $uri/index.html $uri $uri/ /index.php?$query_string; }