Nginx rewrite指令
2013-03-26 by dongnan
举个栗子
下面的nginx
配置文件有两个rewrite
配置示例:
cat /etc/nginx/conf.d/default.conf
server
{
server_name test.com www.test.com;
#... 其它配置项省略
# 访问 test.com,301重定向到 www.test.com
if ($host != 'www.test.com') {
rewrite ^(.*)$ http://www.test.com$1 permanent;
}
location / {
# 伪静态
rewrite ^/$ /index.php?_c=index&_a=index last;
rewrite ^/demo/(.*)/(.*)\.html$ /index.php?_c=$1&_a=$2 last;
}
#... 其它配置项省略
}
测试
使用curl命令测试 rewrite 规则:
curl -IL test.com
HTTP/1.1 301 Moved Permanently
Server: nginx
#...省略
Location: http://www.test.com/
HTTP/1.1 200 OK
Server: nginx
#...省略
返回结果中看到curl
命令共请求了两次:
- 第1次服务器返回
301
状态码test.com
被重定向新的Location: http://www.test.com/
。 - 第2次访问新的地址是
www.test.com
返回200
状态码 。
相对路径
需要说明的是rewrite
正则表达式部分只对相对路径有效:
- 如果你想匹配主机名(比如
test.com
参考上面例子),请与if
指令、$host
变量配合使用。 - 如果你想匹配参数(比如
id=1
参考下面例子),请与if
指令、$query_string
变量配合使用。
什么是相对路径
以 http://www.test.com/demo?id=1
为例:
- 主机名
www.test.com
- 相对路径
/demo
- 参数
?id=1
配置文件:
{
#... 其它配置项省略
if ($query_string ~* "id=(.+)$") {
rewrite ^/ http://demo.com/so.php permanent;
}
}
rewrite 指令
- 语法:
rewrite regex replacement flag
- 默认值:
none
- 使用字段:
server, location, if
- 功能: 按照相关的正则表达式或者字符串来重写URI,
rewrite
指令按照在配置文件中出现的顺序执行,可以在重写指令后面添加需要的标记。
flag 标记:
last
:完成重写指令,之后搜索相应的URI
或location
。break
:完成重写指令,之后停止搜索。redirect
:返回302
临时重定向,浏览器地址栏会显示跳转后URL地址。permanent
:返回301
永久重定向,浏览器地址栏会显示跳转后URL地址。
引用张宴老师的一段话:
last
与break
,用来实现URI重写,浏览器地址栏URL地址不变,但是在服务器端访问的路径已经发生了变化。redirect
与permanent
,用来实现URL跳转,浏览器地址栏会显示跳转后URL地址。last
与break
是有区别的,last
标记在匹配后继续搜索,而break
标记在匹配后则停止搜索。
因此一般在根 location
中(即 location /{..}
),
或者直接写在 server
标签中的 rewrite
规则使用last
标记,
而在非根 location
中(比如 location /pic/{..}
)使用brea
k标记。
注意:
- 如果替换的字符串以
http(s)://
开头,请求将被301
或者302 URL
重定向,并且不再执行多余的rewrite
指令。 - 正则表达式的一部分可以用圆括号括起来,方便之后按照顺序用
$1-$9
来引用,例如上例中的$1
与$2
引用方式。
if 指令
- 语法:
if (condition) { … }
- 默认值:
none
- 使用字段:
server, location
- 功能: 判断一个条件,如果条件成立则后面的大括号内的指令将执行,相关配置从上级继承。
条件
条件可以是以下任意一个:
变量名称,不成立的值为: ""
(空字符串)"或者一些用0
开始的字符串。
- 变量比较可以使用
=
(表示等于)或者使用!=
(表示不等于)运算符。
正则表达式的模式匹配使用符号 ~*
或~
。
~
为区分大小写的匹配。~*
不区分大小写的匹配(abc
匹配ABC
)。!~
和!~*
意为"不匹配的"。
测试目标 -f/-d/-e/-x
:
- 使用
-f
和!-f
检查一个文件是否存在。 - 使用
-d
和!-d
检查一个目录是否存在。 - 使用
-e
和!-e
检查一个文件,目录或者软链接是否存在。 - 使用
-x
和!-x
检查一个文件是否为可执行文件。