介绍rewrite
之前先说一下一些相关的操作指令。
if
指令
if
指令用来支持条件判断,其语法结构如下:
if (condition) {...}
{…}
中的为满足条件时要执行的配置设置。
if
指令可存在于server
块和location
块中,可以使用以下符号进行比较判断:
= 等于
!= 不等于
~ 大小写敏感的模糊匹配
~* 大小写不敏感的模糊匹配
-f 请求的文件是否存在
-d 请求的目录是否存在
-e 请求的文件或目录是否存在
-x 请求的文件是否可执行
每个操作具有"非"权限,如"!~
"、"!-f
"等
例如判断用户的浏览器是否为IE
(比较新的IE版本已经匹配不到了),则可以使用以下方式:
if ($http_user_agent ~ MSIE) {...}
根据用户请求方式的不同而使用不同的配置:
if ($request_method = GET) {...}
if ($request_method = POST) {...}
break
指令
break
指令可存在于server
块、location
块、if块中,作用是直接跳出当前作用域,在存在break
的作用域中,break
之前的配置生效,break
之后的配置将不会生效。
return
指令
return
指令用于完成对请求的处理,直接向客户端返回相关信息,处于该指令后的nginx
配置都是无效的,该指令可用于server
块、location
块、if
块中。
支持以下语法结构:
return [text] #返回给客户端的响应体内容,可使用变量
return code URL; #返回给客户端的HTTP状态码
return URL; #返回给客户端的URL地址
rewrite
指令
rewrite
指令是实际用来进行rewrite
功能配置的具体指令,使用正则表达式的方法来改变URI
,可同时存在1个或多个指令,按照顺序依次进行处理。
rewrite
指令可以在server
块或location
块中进行配置,语法结构如下:
rewrite regex replacement [flag];
参数说明:
regex
:正则表达式,使用()标记要截取的内容,使用$1~$9获取截取到的内容;replacement
:匹配成功后用于替换被截取内容的字符串,即重写后的地址,如果该字符串是由http(s)开头的,则直接返回此URI给客户端,不再继续向下处理。flag
:设置rewrite对URI的处理行为,有4种标志可设置,分别为:
last
:终止继续在本location块中处理URI,将重写后的URI重新在server块中执行,提供了重写后的URI转入到其它location
块中的机会;
break
:重写后的URI继续在本location
块中执行,不会转入到其它的location块中;
redirect
:重写后的URI返回给客户端,状态代码为203,指明是临时重定向URI,主要用在replacement
不是以http(s)开头的情况下;
permanent
:重写后的URI返回给客户端,状态代码为301,指明是永久重定向URI;
set
指令
set
指令用来设置新的变量,语法结构如下:
set $variable value
示例
下面来看一些具体的例子:
例1
server {
listen 7777;
if ($http_user_agent !~ MSIE) {
rewrite ^/ http://10.0.0.33/Api$uri;
}
}
$uri
是全局变量,与$document_uri
含义相同,截取的都是host
后的部份。
chrome
访问”http://10.0.0.1:7777/a.php?num=99
“,会被rewrite
成”http://10.0.0.33/Api/a.php?num=99
“。
例2
server {
listen 7777;
if ($request_method = GET) {
rewrite ^/ http://10.0.0.33/get$uri;
}
}
访问”http://10.0.0.1:7777/a.php?cc=9c9c
“,会被rewrite
成”http://10.0.0.33/get/a.php?cc=9c9c
“。
例3
server {
listen 7777;
location ^~ /Api
{
rewrite ^/Api(.*) http://10.0.0.33/mapi$1;
}
location ^~ /User
{
rewrite ^/User(.*) http://10.0.0.33/ss$1;
}
}
使用http://10.0.0.1:7777/Api/a.php
进行请求访问,会被重写为http://10.0.0.33/mapi/a.php
。同样,使用http://10.0.0.1:7777/User/b.php
进行请求访问,会被重写为http://10.0.0.33/ss/b.php
。
常用的nginx rewrite
重写规则
本文提供一些常用的rewrite
重写规则,用来美化网页的链接。规则里面的$1$2
你不知道是怎么来的话,只要记住,第一个()
里面的是$1
,第二个()
里面的是$2
.
请求的URL
是给人看的,重写后的URL
是给电脑看的。
执行搜索
这个规则的目的是为了执行搜索,搜索URL
中包含的关键字。
请求的URL //hqidi.com/search/some-search-keywords
重写后URL //hqidi.com/search.php?p=some-search-keywords
重写规则 rewrite ^/search/(.*)$ /search.php?p=$1?;
用户个人资料页面
大多数运行访问者注册的动态网站都提供一个可以查看个人资料的页面,这个页面的URL
包含用户的UID
和用户名
请求的URL //hqidi.com/user/47/dige
重写后URL //hqidi.com/user.php?id=47&name=dige
重写规则 rewrite ^/user/([0-9]+)/(.+)$ /user.php?id=$1&name=$2?;
多个参数
有些网站对字符串参数使用不同的语法,例如 通过斜线“/
”来分隔非命名参数
请求的URL //hqidi.com/index.php/param1/param2/param3
重写后URL //hqidi.com/index.php?p1=param1&p2=param2&p3=param3
重写规则 rewrite ^/index.php/(.*)/(.*)/(.*)$ /index.php?p1=$1&p2=$2&p3=$3?;
类似百科的格式
这种格式特点,一个前缀目录,后跟文章名称
请求的URL //hqidi.com/wiki/some-keywords
重写后URL //hqidi.com/wiki/index.php?title=some-keywords
重写规则 rewrite ^/wiki/(.*)$ /wiki/index.php?title=$1?;
论坛
论坛一般用到两个参数,一个话题标识(topic
)一个出发点(starting post
)
请求的URL //hqidi.com/topic-1234-50-some-keywords.html
重写后URL //hqidi.com/viewtopic.php?topic=1234&start=50
重写规则 rewrite ^/topic-([0-9]+)-([0-9]+)-(.*)\.html$ viewtopic.php?topic=$1&start=$2?;
新网站的文章
这种URL结构的特点,由一个文章标识符,后跟一个斜线,和一个关键字列表组成。
请求的URL //hqidi.com/88/future
重写后URL //hqidi.com/atricle.php?id=88
重写规则 rewrite ^/([0-9]+)/.*$ /aticle.php?id=$1?;
最后一个问号
若被替换的URI
中含有参数(类似/app/test.php?id=5
之类的URI
),默认情况下参数会被自动附加到替换串上,可以通过在替换串的末尾加上?标记来解决这一问题。
rewrite ^/users/(.*)$ /show?user=$1? last;
比较一个加上?
标记和不加?
标记的URL
跳转区别:
rewrite ^/test(.*)$ //hqidi.com/home premanent;
访问//hqidi.com/test?id=5
经过301
跳转后的URL
地址为 //hqidi.com/home?id=5
rewrite ^/test(.*)$ //hqidi.com/home? premanent;
访问//hqidi.com/test?id=5
经过301
跳转后的URL
地址为 //hqidi.com/home