Rewrite
主要的功能就是实现URL
的重写,Nginx
的rewrite
功能是使用nginx
提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url
重写以及重定向。本文给大家讲述实际项目中常用到的rewrite
规则。
Nginx
的rewrite
功能需要PCRE
软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持rewrite的模块,但是也必须要PCRE
的支持
rewrite
是实现URL
重写的关键指令,根据regex
(正则表达式)部分内容,重定向到replacement
,结尾是flag
标记。
nginx rewrite
指令执行顺序server
块的rewrite
指令(这里的块指的是server
关键字后{}包围的区域,其它xx块类似)location
匹配location
中的rewrite
指令如果循环超过10次,则返回500 Internal Server Error
错误。
flag
标志位rewrite
的语法很简单,如:
rewrite regex URL [flag];
rewrite
是关键字,regex
是正则表达式,URL
是要替代的内容,[flag]
是标记位的意思,它有以下几种值:
last
: 相当于Apache的[L]标记,表示完成rewrite
break
: 停止执行当前虚拟主机的后续rewrite
指令集
redirect
: 返回302临时重定向,地址栏会显示跳转后的地址
permanent
: 返回301永久重定向,地址栏会显示跳转后的地址
因为301
和302
不能简单的只返回状态码,还必须有重定向的URL
,这就是return
指令无法返回301,302
的原因了。这里 last
和 break
区别有点难以理解:
last
一般写在server和if中,而break
一般使用在location
中last
不终止重写后的url
匹配,即新的url会再从server
走一遍匹配流程,而break
终止重写后的匹配break
和last
都能组织继续执行后面的rewrite
指令来看一个简单实例:
rewrite ^/listings/(.*)$ /listing.html?listing=$1 last;
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
第一条重写规则中,我们可以使用友好的URL:http://mysite.com/listings/123
代替http://mysite.com/listing.html?listing=123
,就相当于我们在浏览器的地址栏中输入http://mysite.com/listings/123
后,实际访问的URL资源是http://mysite.com/listing.html?listing=123
。
第二条规则中,对形如http://mysite.com/images/bla_500x400.jpg
的文件请求,重写到http://mysite.com/resizer/bla.jpg?width=500&height=400
地址,并会继续尝试匹配location
。
if
指令语法为if(condition){...}
,对给定的条件condition
进行判断。如果为真,大括号内的rewrite
指令将被执行。
来看代码规则:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
} //如果UA包含"MSIE",rewrite请求到/msid/目录下
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
} //如果cookie匹配正则,设置变量$id等于正则引用部分
if ($request_method = POST) {
return 405;
} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
if ($slow) {
limit_rate 10k;
} //限速,$slow可以通过 set 指令设置
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
if ($args ~ post=140){
rewrite ^ http://mysite.com/ permanent;
} //如果query string中包含"post=140",永久重定向到mysite.com
if
指令中,可以使用全局变量,这些变量有:
$args: #这个变量等于请求行中的参数,同$query_string
$content_length: 请求头中的Content-length字段。
$content_type: 请求头中的Content-Type字段。
$document_root: 当前请求在root指令中指定的值。
$host: 请求主机头字段,否则为服务器名称。
$http_user_agent: 客户端agent信息
$http_cookie: 客户端cookie信息
$limit_rate: 这个变量可以限制连接速率。
$request_method: 客户端请求的动作,通常为GET或POST。
$remote_addr: 客户端的IP地址。
$remote_port: 客户端的端口。
$remote_user: 已经经过Auth Basic Module验证的用户名。
$request_filename: 当前请求的文件路径,由root或alias指令与URI请求生成。
$scheme: HTTP协议(如http,https)。
$server_protocol: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr: 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name: 服务器名称。
$server_port: 请求到达服务器的端口号。
$request_uri: 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri: 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri: 与$uri相同。
return
跳转我们有时需要在Nginx
上使用rewrite
做301
地址跳转,比如以下规则:
rewrite ^ $scheme://www.mysite.com$request_uri permanent;
当访问任意url
都会301
永久定向到www.mysite.com
的url
上。这个写法没错,但是因为使用了rewrite
的正则匹配,会损耗一部分资源,nginx
官网不推荐这样写。我们可以使用return
同样可以实现301
跳转,简单实用,看实例:
301
永久定向到新域名
server {
listen 80;
listen 443 ssl;
server_name www.old-name.com old-name.com;
return 301 $scheme://www.new-name.com;
}
以上代码实现了老域名301
跳转到新域名上,假如网站要更换新域名的话使用此方法做301
跳转。
不带www
的域名301
跳转到带www
的域名
server {
listen 80;
listen 443 ssl;
server_name mysite.com;
return 301 $scheme://www.mysite.com$request_uri;
}
http
站点301
跳转到https
站点
server {
listen 80;
server_name www.mysite.com;
return 301 https://www.mysite.com$request_uri;
}
Nginx Rewrite
规则详解Rewrite
规则含义就是某个URL
重写成特定的URL
,从某种意义上说为了美观或者对搜索引擎友好,提高收录量及排名等。
Rewrite
规则的最后一项参数为flag
标记,支持的flag
标记主要有以下几种:
last
:相当于Apache
里的(L)标记,表示完成rewrite
;
break
;本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect
:返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent
:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
last和break用来实现URL重写,浏览器地址栏URL地址不变。
a) 例如用户访问www.test.com
,想直接跳转到网站下面的某个页面,www.test.com/new.index.html
如何来实现呢?
我们可以使用Nginx Rewrite
来实现这个需求,具体如下:
在server
中加入如下语句即可:
rewrite ^/$ http://www.test.com/index01.html permanent;
*
代表前面0或更多个字符
+
代表前面1或更多个字符
?
代表前面0或1个字符
^
代表字符串的开始位置
$
代表字符串结束的位置
.
为通配符,代表任何字符
b) 例如多个域名跳转到同一个域名,nginx rewrite
规则写法如下:
server
{
listen 80;
server_name www.wugk.com wugk.com;
if ($host != ‘www.wugk.com’ ) {
rewrite ^/(.*)$ http://www.wugk.com/$1 permanent;
}
更多深入的rewrite
可以继续学习。