nginx重写rewrite基础及实例分享
nginxrewrite正则表达式匹配
大小写匹配
~为区分大小写匹配
~*为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
文件及目录匹配
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
flag标记
last相当于Apache里的[L]标记,表示完成rewrite
break终止匹配,不再匹配后面的规则。
redirect返回302临时重定向地址栏会显示跳转后的地址。
permanent返回301永久重定向地址栏会显示跳转后的地址。
logcation的几个使用实例:
1)location /{}:匹配任何查询,因为所有请求都以/开头。但是正则表达式规则将被优先和查询匹配。
2)location=/{}:仅仅匹配/
3)location~*\.(gif|jpg|jpeg)$
{
rewrite\.(gif|jpg)$/logo.png;
}:location不区分大小写,匹配任何以gif,jpg,jpeg结尾的文件。
几个实例:
多目录转成参数
要求:abc.domian.com/sort/2=>abc.domian.com/index.php?act=sort&name=abc&id=2
规则配置:
if($host~*(.*)\.domain\.com){ set$sub_name$1; rewrite^/sort\/(\d+)\/?$/index.php?act=sort&cid=$sub_name&id=$1last; }
目录对换
要求:/123456/xxxx->/xxxx?id=123456
规则配置:
rewrite^/(\d+)/(.+)//$2?id=$1last;
再来一个针对浏览器优化的自动rewrite,这里rewrite后的目录可以是存在的;
例如设定nginx在用户使用ie的使用重定向到/nginx-ie目录
规则如下:
if($http_user_agent~MSIE){ rewrite^(.*)$/nginx-ie/$1break; }
目录自动加“/”,这个功能一般浏览器自动完成
if(-d$request_filename){ rewrite^/(.*)([^/])$http://$host/$1$2/permanent; }
以下这些可能就跟广义的rewrite重写无关了
禁止htaccess
location~/\.ht{ denyall; } [code] 禁止多个目录 [code] location~^/(cron|templates)/{ denyall;break; }
禁止以/data开头的文件,可以禁止/data/下多级目录下.log.txt等请求
location~^/data{ denyall; }
禁止单个文件
location~/data/sql/data.sql{ denyall; }
给favicon.ico和robots.txt设置过期时间;这里为favicon.ico为99天,robots.txt为7天并不记录404错误日志
location~(favicon.ico){ log_not_foundoff; expires99d; break; } location~(robots.txt){ log_not_foundoff; expires7d; break; }
设定某个文件的浏览器缓存过期时间;这里为600秒,并不记录访问日志
location^~/html/scripts/loadhead_1.js{ access_logoff; expires600; break; }
Nginx还可以自定义某一类型的文件的保质期时间,具体写法看下文的代码:
location~*\.(js|css|jpg|jpeg|gif|png|swf)${ if(-f$request_filename){ expires 1h; break; } } //上段代码就将js|css|jpg|jpeg|gif|png|swf这类文件的保质期设置为一小时。
防盗链的设置:
防盗链:如果你的网站是个下载网站,下载步骤应该是先经过你的主页找到下载地址,才能下载,为了防止某些网友直接访问下载地址完全不通过主页下载,我们就可以使用防盗链的方式,具体代码如下:
location~*\.(gif|jpg|swf)${ valid_referersnoneblockedstart.igrow.cnsta.igrow.cn; if($invalid_referer){ rewrite^/http://$host/logo.png; } }
文件反盗链并设置过期时间--<盗链多次请求也会打开你的站点的图片啊,所以设置下缓存时间,不会每次盗链都请求并下载这张图片>
location~*^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)${ valid_referersnoneblocked*.jb51.net*.jjonline.com.cn*.lanwei.org*.jjonline.orglocalhost 42.121.107.189; if($invalid_referer){ rewrite^/http://img.jb51.net/forbid.gif; return417; break; } access_logoff; break; }
说明:
这里的return417为自定义的http状态码,默认为403,方便通过nginx的log文件找出正确的盗链的请求地址
“rewrite^/http://img.jb51.net/forbid.gif;”显示一张防盗链图片
“access_logoff;”不记录访问日志,减轻压力
“expires3d”所有文件3天的浏览器缓存
只充许固定ip访问网站,并加上密码;这个对有权限认证的应用比较在行
location\{ allow22.27.164.25;#允许的ipd denyall; auth_basic“KEY”;#认证的一些设置 auth_basic_user_filehtpasswd; }
说明:location的应用也有各种变化,这里的写法就针对了根目录了。
文件和目录不存在的时重定向
if(!-e$request_filename){ #proxy_passhttp://127.0.0.1;#这里是跳转到代理ip,这个代理ip上有一个监听的web服务器 rewrite^/https://www.nhooo.com/none.html; #跳转到这个网页去 #return404;#直接返回404码,然后会寻找root指定的404.html文件 }
域名跳转
server{ listen80; server_namejump.jb51.net;#需要跳转的多级域名 indexindex.htmlindex.htmindex.php;#入口索引文件的名字 root/var/www/public_html/;#这个站点的根目录 rewrite^/https://www.nhooo.com/; #rewrite到这个地址,功能表现:在浏览器上输入jump.jb51.net并回车,不会有任何提示直接变成www.nhooo.com access_logoff; }
多域名转向
server{ listen80; server_namewww.nhooo.comwww.jjonline.org; indexindex.htmlindex.htmindex.php; root/var/www/public_html/; if($host~“jjonline\.org”){ rewrite^(.*)https://www.nhooo.com$1permanent; } }
三级域名跳转
if($http_host~*“^(.*)\.i\.jjonline\.cn$”){ rewrite^(.*)http://demo.jb51.net$1; break; }
域名镜向
server{ listen80; server_namemirror.jb51.net; indexindex.htmlindex.htmindex.php; root/var/www/public_html; rewrite^/(.*)https://www.nhooo.com/$1last; access_logoff; }
某个子目录作镜向,这里的示例是demo子目录
location^~/demo{ rewrite^.+http://demo.jb51.net/last; break; }
以下在附带本博客的rewrite写法,emlog系统的rewrite
location~{ if(!-e$request_filename){ rewrite^/(.+)$/index.phplast; } }
nginxrewrite重写规则配置教程
rewrite可以出现的地方有4个:NGX_HTTP_SRV_CONF,NGX_HTTP_SIF_CONF,NGX_HTTP_LOC_CONF,NGX_HTTP_LIF_CONF。分别对应着:
NGX_HTTP_SRV_CONF:配置文件中的server域中的任何地方;
NGX_HTTP_SIF_CONF:配置文件中server域中的if配置中;
NGX_HTTP_LOC_CONF:配置文件中的location域中的任何地方;
NGX_HTTP_LIF_CONF:配置文件中的location域中的if配置中;
例子:
//... server{ //... rewrite"^/+$"/index.php break; if($uri~*"^/+abc"){ rewrite"^/+abc"/abc/index.phpbreak; } location/xy{ rewrite"^/+xy$"/xy/index.php break; } }
其中location的详细描述和location的强大功能可以在本网站搜索框中输入“ngingxlocation”来搜索。
补充
1,break指令
默认值:none;使用环境:server,location,if;
该指令的作用是完成当前的规则集,不再处理rewrite指令。
2,if指令
默认值:none;使用环境:server,location
该指令用于检查一个条件是否符合,如果条件符合,则执行大括号内的语句。If指令不支持嵌套,不支持多个条件&&和||处理。
A.变量名,错误的值包括:空字符串""或者任何以0开始的字符串 B.变量比较可以使用"="(表示等于)和"!="(表示不等于) C.正则表达式模式匹配可以使用"~*"和"~"符号 D."~"符号表示区分大小写字母的匹配 E."~*"符号表示不区分大小写字母的匹配 F."!~"和"!~*"符号的作用刚好和"~"、"~*"相反,表示不匹配 G."-f"和"!-f"用来判断文件是否存在 H."-d"和"!-d"用来判断目录是否存在 I."-e"和"!-e"用来判断文件或目录是否存在 J."-x"和"!-x"用来判断文件是否为可执行 K.部分正则表达式可以在()内,用$1~$9来访问
3,return指令
语法:returncode;使用环境:server,location,if;
该指令用于结束规则的执行并返回状态码给客户端。
例子,如果访问的URL以".sh"或".bash"结尾,则返回403状态码。
location~.*.(sh|bash)?$ { return403; }
4,rewrite指令
语法:rewriteregexreplacementflag
默认值:none;使用环境:server,location,if
该指令根据表达式来重定向URI,或者修改字符串。指令根据配置文件中的顺序来执行。注意重写表达式只对相对路径有效。如果你想配对主机名,你应该使用if语句,示例如下:
if($host~*www.(.*)) { set$host_without_www$1; rewrite ^(.*)$ http://$host_without_www$1permanent; }
rewrite指令的最后一项参数为flag标记,支持flag标记有:
1.last 相当于apache里面的[L]标记,表示rewrite。
2.break本条规则匹配完成后,终止匹配,不再匹配后面的规则。
3.redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址。
4.permanent 返回301永久重定向,浏览器地址会显示跳转后的URL地址。
使用last和break实现URI重写,浏览器地址栏不变。而且两者有细微差别,使用alias指令必须用last标记;使用proxy_pass指令时,需要使用break标记。
Last标记在本条rewrite规则执行完毕后,会对其所在server{......}标签重新发起请求,而break标记则在本条规则匹配完成后,终止匹配。
一般在跟location中(location/{...})或直接在server标签中编写rewrite规则,推荐使用last标记;在非根location中(location/cms/{...}),则使用break。
如果URI中含有参数(/app/test.php?id=5),默认情况下参数会被自动附加到替换串上,可以通过在替换串的末尾加上?标记来解决这一问题。
例如:
rewrite^/test(.*)$https://www.nhooo.com/home permanent; 访问https://www.nhooo.com/test?id=5会跳转到https://www.nhooo.com/home?id=5
例如:如果将类似URL/photo/123456重定向到/path/to/photo/12/1234/123456.png
Rewrite"/photo/([0-9]{2})([0-9]{2})([0-9]{2})"/path/to/photo/$1/$1$2/$1$2$3.png;
注:如果正则表达式里面有花括号"{"或"}",应该使用双引号或单引号。Linux学习,http://linux.it.net.cn
5。Set指令
语法:setvariablevalue;默认值:none;使用环境:server,location,if;
该指令用于定义一个变量,并给变量赋值。变量的值可以为文本、变量以及文本变量的联合。
例子:set$varname"helloworld";
6,Uninitialized_variable_warn指令
语法:uninitialized_variable_warnon|off
使用环境:http,server,location,if
该指令用于开启和关闭未初始化变量的警告信息,默认值为开启。
7,NginxRewrite可以用到的全局变量
$args,$content_length,$content_type,$document_root,$document_uri,$host,$http_user_agent,$http_cookie,$limit_rate,$request_body_file,$request_method,$remote_addr, $remote_port,$remote_user,$request_filename,$request_uri,$query_string,$scheme,$server_protocol,$server_addr,$server_name,$server_port,$uri
Nginx的Rewrite规则编写实例
1.当访问的文件和目录不存在时,重定向到某个php文件
if(!-e$request_filename) { rewrite^/(.*)$index.phplast; }
2.目录对换/123456/xxxx ====> /xxxx?id=123456
rewrite^/(d+)/(.+)/ /$2?id=$1last;
3.如果客户端使用的是IE浏览器,则重定向到/ie目录下
if($http_user_agent ~MSIE) { rewrite^(.*)$/ie/$1break; }
4.禁止访问多个目录
location~^/(cron|templates)/ { denyall; break; }
5.禁止访问以/data开头的文件
location~^/data { denyall; }
6.禁止访问以.sh,.flv,.mp3为文件后缀名的文件
location~.*.(sh|flv|mp3)$ { return403; }
7.设置某些类型文件的浏览器缓存时间
location~.*.(gif|jpg|jpeg|png|bmp|swf)$ { expires30d; } location~.*.(js|css)$ { expires1h; }
8.给favicon.ico和robots.txt设置过期时间;
这里为favicon.ico为99天,robots.txt为7天并不记录404错误日志
location~(favicon.ico){ log_not_foundoff; expires99d; break; } location~(robots.txt){ log_not_foundoff; expires7d; break; }
9.设定某个文件的过期时间;这里为600秒,并不记录访问日志
location^~/html/scripts/loadhead_1.js{ access_log off; root/opt/lampp/htdocs/web; expires600; break; }