Rewtrite : 其主要目的是为了进行URL 重写,进行URL重定向。主要采用PCRE: Perl Compatible Regular Expressions(Perl兼容正则表达式语法)进行规则匹配,所以需要先安装PCRE lib。
一 rewrite规则
重写规则是rewirte的基础。在Nginx中,使用ngx_http_rewrite_module模块支持URL重写。该模块是标准的http模块。
二 if指令
用来支出条件判断,并且根据条件判断结果选择不同的Nginx配置,可以在server块或者location块中配置,语法结构:
if (condition) {…….}
对于condition而言:
# 变量名:如果变量的值为空字符串或者以0开头的任意字符串,if指令认为条件为false,其他情况认为条件为true,比如:
if($slow) {
//nginx配置
}
# 比较字符串是否相等,字符串无需加引号
if ($request_method = POST) {
return405;
}
# 使用正则表达式对变量进行匹配,匹配成功时,if条件指令为true,否则为false。
变量与正则表达式之间用"~""~*" "!~" "!~*" 连接,
"~":大小写敏感
"~*": 大小写不敏感
"!~":"~" 和"~*"匹配失败时,if指令认为条件为true,否则为false
if ($http_user_agent ~ MSIE) {
#$http_user_agent 是否包含MSIE字符
}
# 文件和目录是否存在,文件是否可执行
文件是否存在:使用-f 和 !-f
目录是否存在:使用-d 和 !-d
文件是否可执行:使用-x和!-x
if (-f $reqeust_filename) {
//......
}
三 break、return指令
3.1 break指令
该指令用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置,位于他前面的指令配置生效,位于后面的指令配置无效。该指令可以在server块和location块以及if块中使用。
location / {
if($slow) {
set$id $1
break;
limit_rate10k
}
}
3.2 return指令
该指令用于完成队请求的处理,直接向客户端返回响应状态码。处于该指令后的所有Nginx配置是无效的。该指令可以在server或者location或者if块中使用。
return [ text]
return code URL;
return URL;
code: 表示返回给客户端的状态码
text: b表示相应的具体响应体内容
URL: 没有状态码的URL视为一个302状态码
四 rewrite指令
该指令通过正则表达式的使用来改变URI,可以同时存在一个或者多个指令,按照顺讯一次对URL进行匹配和处理。我们也可以理解我对于多条rewrite指令,顺序靠前的且匹配的优先执行。
语法格式:
rewrite regex replacement [flag];
regex: 用于匹配URI的正则表达式,使用括号()标记要截取的内容
replacement: 匹配成功后用于替换URI中被截取内容的字符串。默认情况下如果该字符串是由http://或者https://开头的,则不会继续向下对URI进行其他处理
flag: 用来设置rewrite对URI的处理行为,选项有:
# last: 停止当前这个请求,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行。
# break:相对last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段。
# redirect: 重写后的URI返回给客户端,状态码为302,指明是临时重定向
# permanent:重定向的URI返回给客户端,状态码为空301,指明是永久重定向
rewrite a.example.com http://b.example.com$request_uri? permanent;
location/break/ {
rewrite ^/break/(.*) /test/$1 break;
echo"break page";
}
location/last/ {
rewrite ^/last/(.*) /test/$1 last;
echo"last page";
}
location/test/ {
echo"test page";
}
结果如下:
[dubbo@docker conf]$ curlhttp://a.example.com/break/1111
break page
[dubbo@docker conf]$ curl http://a.example.com/test/2222
test page
[dubbo@docker conf]$ curlhttp://a.example.com/last/3333
test page
五 rewrite_log指令
rewrite_log on | off
该指令配置是否开启URL重写日志输出功能
六 set指令
用于设置一个新的变量,语法结构为:
set 变量名 变量值
七 rewrite常用全局变量
八 域名跳转
server {
listen80;
server_namejump.myweb.com;
rewrite^/ http://www.myweb.info/;
}
server {
listen80;
server_namejump.myweb.name jump.myweb.info;
if($host ~ myweb\.info) {
rewrite^(.*) http://jump.myweb.name/$1 permanent;
}
}
九 域名镜像
镜像网站是指将一个完全相同的网站,分被放置到几个服务器上,并分别使用独立的URL,其中一个服务器上的网站叫做主站,其他的为镜像网站。镜像网站可以保存网页信息,历史性数据等,可以通过镜像网站提高在不同的地区响应速度,平衡网站的流量负载,解决网络带宽限制和封锁等
使用Nginx的rewrite实现镜像域名的跳转,原理就是将不同的镜像URL重写到相同的URL就可以了。
十 独立域名
当一个网站包含多个板块的时候,可以为其中某些板块设置独立的域名。
server {
listen80;
server_namebbs.exampel.com;
rewrite^(.*) http://www.example.com/bbs$1 last;
break;
}
server {
listen81;
server_namehome.exampel.com;
rewrite^(.*) http://www.example.com/home$1 last;
break;
}
十一 目录自动添加/
一般情况,对于网站默认的资源,我们不加具体的URL访问是可以的,比如访问www.example.com的时候,如果我们设置了站点的首页是index.html 那么直接访问www.example.com就可以成功访问。
但是如果请求的资源文件在二级目录下呢,这样的习惯无法正常访问资源,比如访问http://www.example.com/bbs/index.html时,如果URL省略为http://www.example.com/bbs,将末尾的斜杠也省了,访问就出问题,即Nginx服务器访问二级目录时不加斜杠无法访问。但是我们不可能要求客户端始终按照我们的要求在末尾加斜杠。如何解决呢?
server {
listen80;
server_namewww.example.com;
location^~ /bbs {
if(-d $request_filename) {
# 表示任意域名非/结尾 重定向到该任意域名以斜杠结尾
rewrite^/(.*) ([^/])$ http://$host/$1$2/ permanent;
}
}
}
十二 目录合并
有时候我们的网站的资源目录是多层级的,比如:
http://www.example.com/11/22/45/1023.html
这种方式不利于搜索引擎搜索,那么我们会尝试想办法让URL的目录级数看上去少一些呢?
server {
listen80;
server_name www.example.com;
location^~ /server {
rewrite^/server/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)\.html$/server-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.html last;
break;
}
}
十三 防盗链
盗链是一种损害原有网站的合法利益,给原有网站所在的服务器造成额外的负担的非法行为。要采取防盗链的措施,首先理解盗链的实现原理:
比如我们自己网站的图片,是引用其他服务器的图片资源,那么客户端获取图片的请求,就是从其他服务器上下载的,这样对其他服务器不是很公平,增加了网络带宽。
要实现防盗链,HTTP头部的Referer头域和采用URL的格式访问当前网页或者文件的原地址。通过该头域可以检测到Referer头域中值并不是自己站点的URL,就采取阻止措施。
但是Referer头域的值是可以更该的,该方法不能够完全阻止所有的盗链行为。
valid_referers none | blocked | server_names|string......;
none: 检测Referer头域不存在
blocked: 检测Referer头域的值被防火墙或者代理服务器删除或者伪装的情况
server_names: 设置一个或者多个URL,查看Referer头域的值是这些的URL中的某个
server {
listen80;
server_namewww.example.com;
location~* ^.+\.(gif|jpg|png|swf|flv|rar|zip)$ {
valid_referersnoen blocked server_names *.ecom.com
if($valid_referers) {
rewrite^/ http://www.example.com/images/forbbiden.png
}
}
}