Environment: nginx version is 1.2.6
Recently, I encountered a strange problem while working on a project. Because I wanted to redesign the URL, I used the following nginx rewrite rules:
if (-f $request_filename/index.html){ rewrite (.*) /index.html break; } if (-f $request_filename/index.php){ rewrite (.*) /index.php; } if (!-f $request_filename){ rewrite (.*) /index.php; }
This rewriting rule has been commonly used, and I don’t know if there is anything wrong with it~ (please give me some advice)
When I did not use these rules, a slash would be automatically added when accessing an existing directory on the server. At this time, nginx's automatic rewrite rules were triggered. This is normal and no problem.
But after I added the above rules, slashes will not be automatically added when accessing folders that already exist on the server. Moreover, after repeated testing, I found that the 2nd and 3rd rules were causing trouble:
1. If you only delete the second rule, then no matter whether your folder exists or not, it will be detected as not existing, and no slash will be added, and it will directly enter the third rule, and finally match it and enter the index. php, you can know that it is processed by file at this time.
2. If the second rule is deleted, the judgment of the file in the third rule -f
is changed to -e
, that is, the file or folder:
if (!-e $request_filename){ rewrite (.*) /index.php; }
At this time, the problem is solved. If the directory exists, a slash will be added automatically. If it does not exist, it will match and enter index.php. This is exactly what I want.
I am very confused, please give me some advice, why is it like this?
In addition, due to some original problems of the project, there are a lot of other targeted rewrite rules in the third rule, so I don’t want to enter the third rule when the input folder is and it exists. rules to match rules, although the performance impact is not significant.
After many tests, I figured it out myself.
There is nothing wrong with these three rules, and the second one is not weird as I said before.
First, nginx will match according to user-defined rules. When the path you enter exists and does not contain a slash at the end,
Since index.php exists in my folder,
$request_filename/index.php
匹配第二条规则成功,注意这里的/
, and then perform subsequent matching. In other words, as long as this folder exists and there is index.html or index.php in this folder, it will match the first or second rule I gave above, there is no doubt about it.So, if you want to avoid matching after the first or second rule and automatically add slashes when the folder exists, the solution is to add a judgment on the folder before the first rule:
The meaning of this rule is that if the folder exists and there is no slash, it will automatically add a slash and perform a 301 jump. OK, the problem is solved.
The logic of the last one is that if the previous conditions are not met, "if the accessed path is not a file", it will automatically jump to /index.php.
Suggestion: Insert a sentence -e before the third item to check whether it is a folder. If so, automatically add a slash and break.
Not tested, for reference only.