第一个好主意是将重定向规则放在单独的文件中。这将使主要配置更具可读性。然后可以将具有规则的文件包含在include指令中。
另一个好主意是使用map而不是if
,因为它具有更简洁的语法来定义长列表。
假设您决定将规则放入/path/to/redirect/rules.conf
. 该文件的内容将如下所示:
# Each map defines the set of rules for one set of conditions.
# The blocks must be sorted in order of priority: every next
# map block has a higher priority than the previous one.
map $arg_p $p_condition {
default "";
4 /2012/12/hello-world;
15 /about;
# You can use regular expressions
~^1[6-9]$ /some/page;
}
# By combining the condition variables you can implement
# some sort of and/or/not logic in your rules
map "${arg_p}#${arg_q}" $pq_condition {
# Note that it is necessary to inherit the result
# of the previous map block to preserve them. And this
# is where the priority of the blocks comes from
default $p_condition;
# The values of p _and_ q are 4 and 15
4#15 /2012/12/hello-world;
# The value of p is 5 _or_ the value of q is 16
~"^5#.*" /another/page;
~"^.*?#16" /another/page;
# The value of p is _not_ 8 _and_ the value of q is 30
~"^[^8]#30" /the/very/special/page;
}
# The final block is of the highest priority. It defines
# the variable, which value will be used as the URL for redirection
map $args $url_to_redirect_to {
# Don't forget this important line
default $pq_condition;
# Here's another type of condition: check if the t variable
# is present in the list of GET paramters
~^(&|\?)t=.*$ /yet/another/page;
}
现在剩下要做的就是使用主配置中定义的规则:
# Note that map directives must be placed out of the `server` block
include /path/to/redirect/rules.conf;
server {
...
location = / {
...
if ($url_to_redirect_to != "") {
rewrite ^ $url_to_redirect_to? permanent;
}
...
}
...
}
乍一看,map
块的级联可能看起来有些混乱,但是当您在其中放置大量规则时,您会看到这种方法的优势。