Nginx重写规则指南

  • A+
所属分类:Nginx

当运维遇到要重写情况时,往往是要程序员把重写规则写好后,发给你,你再到生产环境下配置。对于重写规则说到底就是正则匹配,做运维的岂能对正则表达式不了解的?最起码最基本的正则表达式会写。套用一句阿里的话(某网友说是阿里说的,不清楚到底是不是出自阿里)“不懂程序的运维,不是好运维;不懂运维的开发,不是好开发。”。 正则表达式也是一门语言哈。当你学习一门语言时,必然会遇到该门语言的正则表达式这章节的。 在这里推荐一本非常好的正则表达式书,包含常用的语言的正则写法如sed、perl、bash、awk、php、c#、java、javascript、python、ruby等等,《Regular Expressions Cookbook, 2nd Edition》,也有中文版的,大家可以到网络上找找。
介绍nginx的重写模块,创建重写规则向导,便于快捷正确的创建新的重写规则,不求救于人。同时,如果想把apache转换成nginx,重写规则也是要改的咯。

一. rewrite模块介绍

nginx的重写模块是一个简单的正则表达式匹配与一个虚拟堆叠机结合。依赖于PCRE库,因此需要安装pcre。根据相关变量重定向和选择不同的配置,从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后nginx将返回500错误。同时,重写模块包含set指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。

二. rewrite模块指令

break
语法:break
默认值:none
使用字段:server, location, if
完成当前设置的重写规则,停止执行其他的重写规则。

if
语法:if (condition) { … }
默认值:none
使用字段:server, location
注意:尽量考虑使用trp_files代替。
判断的条件可以有以下值:
1. 一个变量的名称:空字符传”“或者一些“0”开始的字符串为false。
2. 字符串比较:使用=或!=运算符
3. 正则表达式匹配:使用~(区分大小写)和~*(不区分大小写),取反运算!~和!~*。
4. 文件是否存在:使用-f和!-f操作符
5. 目录是否存在:使用-d和!-d操作符
7. 文件、目录、符号链接是否存在:使用-e和!-e操作符
8. 文件是否可执行:使用-x和!-x操作符

return
语法:return code
默认值:none
使用字段:server, location, if
停止处理并为客户端返回状态码。非标准的444状态码将关闭连接,不发送任何响应头。可以使用的状态码有:204,400,402-406,408,410, 411, 413, 416与500-504。如果状态码附带文字段落,该文本将被放置在响应主体。相反,如果状态码后面是一个URL,该URL将成为location头补值。没有状态码的URL将被视为一个302状态码。

rewrite
语法:rewrite regex replacement flag
默认值:none
使用字段:server, location, if
按照相关的正则表达式与字符串修改URI,指令按照在配置文件中出现的顺序执行。可以在重写指令后面添加标记。
注意:如果替换的字符串以http://开头,请求将被重定向,并且不再执行多余的rewrite指令。
尾部的标记(flag)可以是以下的值:
last - 停止处理重写模块指令,之后搜索location与更改后的URI匹配。
break - 完成重写指令。
redirect - 返回302临时重定向,如果替换字段用http://开头则被使用。
permanent - 返回301永久重定向。

rewrite_log
语法:rewrite_log on | off
默认值:rewrite_log off
使用字段:server, location, if
变量:无
启用时将在error log中记录notice级别的重写日志。

set
语法:set variable value
默认值:none
使用字段:server, location, if
为给定的变量设置一个特定值。

uninitialized_variable_warn
语法:uninitialized_variable_warn on|off
默认值:uninitialized_variable_warn on
使用字段:http, server, location, if
控制是否记录未初始化变量的警告信息。

三. 重写规则组成部分

3.1 任何重写规则的第一部分都是一个正则表达式
可以使用括号来捕获,后续可以根据位置来将其引用,位置变量值取决于捕获正则表达式中的顺序,$1引用第一个括号中的值,$2引用第二个括号中的值,以此类推。如: