nginx rewrite相关
nginx rewrite相关功能
ngx_http_rewrite_module
用于实现URL的重写,URL的重写是非常用的功能
https://nginx.org/en/docs/http/ngx_http_rewrite_module.html
if指令
if (条件匹配) {
action
}
1 =: #⽐较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false。 2 !=: #⽐较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false。 3 ~: #表⽰在匹配过程中区分⼤⼩写字符,(可以通过正则表达式匹配),满⾜匹配条件为真,不满⾜为假。 4 !~:#为区分⼤⼩写字符且匹配结果不匹配,不满⾜为真,满⾜为假。 5 ~*: #表⽰在匹配过程中不区分⼤⼩写字符,(可以通过正则表达式匹配),满⾜匹配条件为真,不满⾜为假。 6 !~*: #为不区分⼤⼩字符且匹配结果不匹配,满⾜为假,不满⾜为真。 7 -f 和 ! -f: #判断请求的⽂件是否存在和是否不存在 8 -d 和 ! -d: #判断请求的⽬录是否存在和是否不存在。 9 -x 和 ! -x: #判断⽂件是否可执⾏和是否不可执⾏。 10 -e 和 ! -e: #判断请求的⽂件或⽬录是否存在和是否不存在(包括⽂件,⽬录,软链接)。
实例:
1 location /main { 2 index index.html; 3 default_type text/html; 4 5 if ( $scheme = http ){ 6 echo "if------> $scheme"; 7 } 8 if ( $scheme = https ){ 9 echo "if -----> $scheme"; 10 } 11 if ( -f $request_filename){ 12 echo "file is exist"; 13 } 14 if (!-f $request_filename){ 15 echo "file is not exist"; 16 return 409; 17 } 18 }
如果$变量的值为空字符串或是以0开头的任意字符串,则if指令认为该条件为false,其他条件为true。
set指令:
1 location /main { 2 root /data/nginx/html/pc; 3 index index.html; 4 default_type text/html; 5 set $name magedu; 6 echo $name; set $my_port $server_port; 7 echo $my_port; 8 }
break指令
⽤于中断当前相同作⽤域(location)中的其他Nginx配置,与该指令处于同⼀作⽤域的Nginx配置中,
位于它前⾯的 配置⽣效,位于后⾯的指令配置就不再⽣效了,Nginx服务器在根据配置处理请求的过程中
遇到该指令的时候,回 到上⼀层作⽤域继续向下读取配置,该指令可以在server块和location块以及if块中使⽤,使⽤语法如下:
1 location /main { 2 root /data/nginx/html/pc; 3 index index.html; 4 default_type text/html; 5 set $name magedu; 6 echo $name; break; 7 set $my_port $server_port; 8 echo $my_port; 9 }
return指令
return⽤于完成对请求的处理,并直接向客⼾端返回响应状态码,⽐如其可以指定重 定向URL(对于特殊重定向状态码,301/302等)
或者是指定提⽰⽂本内容(对于特殊状态码403/500等),处于此指令 后的所有配置都将不被执⾏,
1 return可以在server、if和location块进⾏配置,⽤法如下: 2 return code; #返回给客⼾端指定的HTTP状态码 3 return code (text); #返回给客⼾端的状态码及响应体内容,可以调⽤变量 4 return code URL; #返回给客⼾端的URL地址
实例:
1 location /main { 2 root /data/nginx/html/pc; 3 default_type text/html; 4 index index.html; 5 if ( $scheme = http ){ 6 #return 666; 7 #return 666 "not allow http"; 8 #return 301 http://www.baidu.com; 9 return 500 "service error"; 10 echo "if-----> $scheme"; 11 #return后⾯的将不再执⾏ 12 } 13 if ( $scheme = https ){ 14 echo "if ----> $scheme"; 15 }
rewrite_log指令(基本不用)
设置是否开启记录ngx_http_rewrite_module 模块日志记录到error_log日志文件当中,可以配置在http、server、location或if
当中,需要日志级别为notice
1 location /main { 2 index index.html; 3 default_type text/html; 4 set $name magedu; 5 echo $name; 6 rewrite_log on; 7 break; 8 set $my_port $server_port; 9 echo $my_port; 10 }
rewrite指令
rewrite regex replacement [flag];
rewrite ^(.*) http://www.baidu.com break;
注意: 如果在同⼀级配置块中存在多个rewrite规则,那么会⾃下⽽下逐个检查;被某条件规则替换完成后,
会重新⼀轮 的替换检查,隐含有循环机制,但不超过10次;如果超过,提⽰500响应码,
[flag]所表⽰的标志位⽤于控制此循环 机制,如果替换后的URL是以http://或https://开头,则替换结果会直接以重向返回给客⼾端, 即永久重定向301
rewrite flag 介绍
rewrite regex replacement [flag];
nginx的rewrite的指令,实现url的重新跳转,rewrite有四种flag redirect(临时重定向) permanem(永久重定向) break及last
前两种是跳转型flag,后两种是达理型,条转型是指有客户端浏览器重新对新地址进行请求, 代理型是在WEB服务器内部实现跳转的。
redirect; #临时重定向,重写完成后以临时重定向⽅式直接返回重写后⽣成的新URL给客⼾端,由客⼾端重新发起请求;使⽤相对 路径,或者http://或https://开头,状态码:302 permanent; #重写完成后以永久重定向⽅式直接返回重写后⽣成的新URL给客⼾端,由客⼾端重新发起请求,状态码:301 last; #重写完成后停⽌对当前URI在当前location中后续的其它重写操作,⽽后对新的URL启动新⼀轮重写检查,不建议在 location中使⽤ break; #重写完成后停⽌对当前URL在当前location中后续的其它重写操作,⽽后直接将匹配结果返还给客⼾端即结束循环并 返回数据给客⼾端,建议在location中使⽤
rewrite案例 域名永久与临时重定向
永久重定向: 会缓存DNS解析记录
临时重定向: 不会缓存当前域名的解析记录
将访问源域名 www.magedu.net 的请求永久重定向到 www.magedu.com
临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。
location / { root /data/nginx/html/pc; index index.html; rewrite / http://www.magedu.com permanent; #rewrite / http://www.magedu.com redirect; }
rewrite案例 break与last
访问about的请求被转发至images,而访问images传递请求再次转发至images1
1 break案例 2 cat /usr/local/nginx/break/index.html 3 break 4 cat /usr/local/nginx/test1/index.html 5 test1 6 cat /usr/local/nginx/test2/index.html 7 test2 8 location /break { 9 root /usr/local/nginx; 10 index index.html; 11 #break匹配成功后不再向下匹配,也不会跳转到其他的location,即直接结束匹配并给客户端返回结果数据。 12 rewrite ^/break/(.*) /test1/$1 break; 13 #break 不会屁屁额后面的rewrite规则也不匹配其他location 14 rewrite ^/test1/(.*) /test2/$1 break; 15 } 16 location = /test1 { 17 retrun 999 "new test1"; 18 } 19 location = /test2 { 20 return 666 "new test2"; 21 } 22 #最终的结果不会超过break的location而且不会继续匹配当前location后续的write规则,而且直接返回数据给客户端。 23 curl -L http://www.magedu.net/break/index.html 24 test1
break使用于不改变客户端访问方式,但是要将访问的目的URL做单词重写的场景,比如有v1/v2两个版本的网站前端页面
并存,旧版本的网站数据已经保存到了statics不能丢失,但是要将访问新版本的资源重写到新的静态资源路径到新的目录static:
location /statics { root /data/nginx; index index.html; rewrite ^/statics/(.*) /static/$1 break; }
last案例:
last 使用于要不改变客户端访问方式但是需要做多次目的的URL重写的场景,场景不是很多。
对某个location的URL匹配成功后悔停止当前location的后端rewrite规则,病结束当前location,然后将匹配生成的新URL跳转
至其他location继续匹配,知道没有location可匹配后将最后一次location的数据返回给客户端。
1 location /test1 { 2 index index.html; 3 root /usr/local/nginx; 4 rewrite ^/test1/(.*) /test2/$1 last; 5 } 6 location /test2 { 7 return 666 "new test2"; 8 } 9 location /last { 10 root /usr/local/nginx; 11 index index.html; 12 rewrite ^/last/(.*) /test1/$1 last; 13 #rewrite ^/test1/(.*) /test2/$1 last;#如果第一条rewrite规则匹配成功则不执行本条,否则执行本条rewrite规则。 14 } 15 curl -L http://www.magedu.net/last/index.html 16 new test2 #会匹配多个location,直到最终全部匹配完成,返回最后一个location的匹配结果给科幻短。
rewrite案例-自动跳转https:
http强制跳转https
server块内 server { listen 80; server_name www.magedu.net; } rewrite ^(.*)$ https://$host$1;
另外一只节省资源的做法
index.html <html> <meta http-equiv="refresh" content="0;url=https://www.baidu.com"> </html> location块内 server { listen 443 ssl; listen 80; server_name www.magedu.net; ... location / { root /usr/local/nginx/html/pc; index index.html; if {$scheme = http }{ #不加条件判断会导致死循环 rewrite / https://www.magedu.net pernament; } } }
rewrite-判断文件是否存在-跳转
1 location { 2 root /usr/local/nginx/html/pc; 3 index index.html; 4 if (!-f $request_filename){ 5 #return 404 '页面不存在' 6 rewrite (.*) http://www.magedu.net/index.html; 7 } 8 }