灵活应用Nginx Rewrite:实战经验与实用方法
Nginx Rewrite顺序优先级
location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)
具体而言,当 Nginx 匹配请求 URL 时,先按照完全匹配(location =)进行匹配,然后是完整路径匹配(location 完整路径),接着是路径前缀匹配(location ^~ 路径),再然后是正则表达式匹配(location ,* 正则顺序),最后是部分起始路径匹配(location 部分起始路径),如果都没有匹配成功,则使用 / 作为默认匹配。
Nginx Rewrite Flag
Nginx Rewrite 指令中的 flag 用于控制重写操作的行为,常见的 flag 有以下几种:
last:相当于 Apache 中的 [L] 标记,表示完成重写操作,并跳过后续的 Rewrite 指令,直接选择下一个匹配的 location 进行处理。
break:终止当前匹配,不再执行后续的 Rewrite 指令,并使用当前重写后的 URL 进行请求处理。
redirect:返回 302 临时重定向,地址栏会显示跳转后的 URL,对搜索引擎爬虫来说不会更新 URL(因为是临时重定向)。
permanent:返回 301 永久重定向,地址栏会显示跳转后的 URL,对搜索引擎爬虫来说会更新 URL(因为是永久重定向)。
last 和 break 在使用上区别:
last 和 break 当出现在 location 块之外时:
两者的作用是一致的没有任何差异, 他们会跳过所有的在他们之后的 rewrite 模块中的指令, 去选择自己匹配的location.
不写last和break, 会优先执行rewrite部分, 然后才会去匹配 location 块.
last 和 break 当出现在 location 块内部时
break: url重写后, 直接使用当前资源, 终止当前location的rewrite检测, 而且不再进行location匹配, 完成本次请求, 地址栏url不变.
last: url重写后, 马上发起一个新的请求, 再次进入server块, 重试location匹配, 超过10次匹配不到报500错误, 地址栏url不变.
不写last和break, 那么流程就是依次执行这些rewrite.
例子
如下 Nginx配置,回答下面3个问题
1 当 1 这条rewrite 规则生效后, 2,3,4规则将会如何处理。
2 当 5 这个 rewrite 指令处理完成之后,将会如何处理请求。
3 第二个location 中的 rewrite(6)指令处理完成之后,将会如何处理请求。
rewrite xxx1 yyy last; 1
rewrite xxx2 yyy last; 2
rewrite xxx3 yyy last; 3
rewrite xxx4 yyy last; 4
location ~ url1
{
rewrite url1 url2 last; 5
}
location ~ url2
{
rewrite url3 url4 break; 6
fastcgi_pass 127.0.0.1:9000
}
当 1 这条rewrite 规则生效后, 它后面的2,3,4将被跳过不做判断, 而去直接选择 后面的location.
当 5 这个 rewrite 指令处理完成之后, 会跳出location, 再重新判断rewrite 1-4 的规则.
第二个location 中的 rewrite(6)指令处理完成之后, 不会跳出location, 更不会重新判断rewrite 1 ~ 4 的规则. 而只能将信息传递给后面的 fastcgi_pass 或者 proxy_pass 等指令。
Nginx请求匹配到下面的localtion会返回404吗
location /eoc {
rewrite ^ $request_uri;
rewrite ^/eoc/(.*)$ /$1 break;
rewrite ^/eoc break;
return 404;
proxy_pass http://127.0.0.1:18002$uri;
proxy_http_version 1.1;
add_header Cache-Control 'public, max-age=0';
}
根据 Nginx 的请求处理过程,当执行了 return 指令时,后续的rewrite和return指令不会执行,而是将其扔给了 fastcgi_pass 或者是 proxy_pass 指令去处理,而不会执行"return 404;"。因此,配置中的"return 404;"不会被执行。