ngx_http_rewrite_module模块
常用正则表达式:
字符 描述
\ 将后面接着的字符标记为一个特殊字符或者一个原义字符或一个向后引用
^ 匹配输入字符串的起始位置
$ 匹配输入字符串的结束位置
* 匹配前面的字符零次或者多次
+ 匹配前面字符串一次或者多次
? 匹配前面字符串的零次或者一次
. 匹配除“\n”之外的所有单个字符
(pattern) 匹配括号内的pattern
1.if (condition) { ... }
1.if (condition) { ... } 条件满足时,执行配置块中的配置指令;server, location 比较操作符condition: =: #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false。 !=: #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false。 ~: #表示在匹配过程中区分大小写字符,(可以通过正则表达式匹配),满足匹配条件为真,不满足为假。 ~*: #表示在匹配过程中不区分大小写字符,(可以通过正则表达式匹配),满足匹配条件为真,不满足为假。 !~: #为区分大小写字符且匹配结果不匹配,不满足为真,满足为假。 !~*: #为不区分大小字符且匹配结果不匹配,满足为假,不满足为真。 -f 和 ! -f: #判断请求的文件件是否存在和是否不存在 -d 和 ! -d: #判断请求的目录是否存在和是否不存在。 -x 和 ! -x: #判断文件件是否可执行和是否不可执行。 -e 和 ! -e: #判断请求的文件件或目录是否存在和是否不存在(包括文件,目录,软链接)。 注意: if (condition) { ... } 语句中,如果$变量的值为空字符串或是以0开头的任意字符串,则 if 指令认为该条件为false,其它条件为true 示例: http跳转到https server { listen 80; listen 443 ssl; server_name rewrite.zjol.com.cn; ssl_certificate /usr/local/nginx/ssl/zjol2022.pem; ssl_certificate_key /usr/local/nginx/ssl/zjol2022.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; charset GB2312; location /rewrite { root /data/nginx/html/; index index.html; default_type text/html; if ( $scheme = https){ echo "if-----> $scheme"; echo AAAAAAAAA; #测试这段时,这里会返回结果 #return 301 https://www.magedu.net/; } echo BBBBBBBB;#测试这段时,这里不返回结果,说明if判断后直接返回结果
#如果下面还有if语句并为真是,会覆盖BBBBB或AAAAAA的结果。 if ( $scheme = http){ echo "if-----> $scheme"; } } location /rewrite1 { if (-f $request_filename) { echo $request_filename; echo "file is exist"; #return 409; } if (!-f $request_filename) { echo $request_filename; echo "file is not exist"; #return 409; } }}
2.return 返回客户端指定的状态码,多条只执行第一条。
return code [text]; #返回客户端指定的状态码和文本说明
return code URL; #返回客户端指定的状态码和URL
return URL; #返回客户端指定的URL
停止处理,并返回给客户端指定的响应码(包括: 204, 400, 402 — 406, 408, 410, 411, 413, 416, 500 — 504),并对 301, 302, 303, 307, 308跳转到URL
使用curl访问跳转到指定URL
location / { if ( $http_user_agent ~* curl ){ # return return http://www.abc.com;
}
}
测试方法: curl -I -A curl http://www.abc.com
location /rewrite2 {
if ( $scheme = https ){
#return 666;
#return 666 "not allow http";
return 301 http://www.baidu.com;
#return 500 "service error";
echo "if-----> $scheme";#echo不执行
}
}
测试结果
[root@localhost7D ~]# curl -I -A crul https://rewrite.zjol.com.cn/rewrite2/
HTTP/1.1 666
Server: nginx/1.17.1
Date: Sun, 17 Jul 2022 08:30:51 GMT
Content-Length: 0
Connection: keep-alive
[root@localhost7D ~]# curl -I -A crul https://rewrite.zjol.com.cn/rewrite2/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.17.1
Date: Sun, 17 Jul 2022 08:31:38 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://www.baidu.com
禁止访问http
if ($host != "xinpan.zzhz.zjol.com.cn") {
return 403;
}
3.rewrite_log on | off;
是否开启重写日志, 发送至error_log(notice level) (记录要修改notice level)
location /main { index index.html; default_type text/html; set $name magedu; echo $name; rewrite_log on; break; set $my_port $server_port; #记录的是my_port错误,由于break退出,后面的变量有错误。 echo $my_port; }
tail -f /usr/local/nginx/logs/error.log
2022/07/17 17:21:36 [warn] 51626#0: *146 using uninitialized "my_port" variable, client: 192.168.80.1,
server: rewrite.zjol.com.cn, request: "GET /main/ HTTP/1.1", host: "rewrite.zjol.com.cn
4.rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在⼀个或多个指令,按照顺序依次对URI进⾏匹配,rewrite主要是针对⽤⼾请求的URL或者是URI做具体处理,以下是URL和URI的具体介绍:
URI(universal resource identifier):通⽤资源标识符,标识⼀个资源的路径,可以不带协议。
URL(uniform resource location):统⼀资源定位符,是⽤于在Internet中描述资源的字符串,是URI的⼦集,主要包括传输协议(scheme)、主机(IP、端⼝号或者域名)和资源具体地址(⽬录和⽂件名)等三部分,⼀般格式为
scheme://主机名[:端⼝号][/资源路径],如:http://www.a.com:8080/path/file/index.html就是⼀个URL路径,URL必须带访问协议。
每个URL都是⼀个URI,但是URI不都是URL。
例如:
http://example.org:8080/path/to/resource.txt #URI/URL
ftp://example.org/resource.txt #URI/URL
/absolute/path/to/resource.txt #URI
rewrite regex replacement [flag];
将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查
隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制
如果replacement是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301
rewrite flag使⽤介绍
[flag]:
last: 重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环,不建议在 location中使用。
break: 重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块后的其它配置;结束循环。
redirect: 临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;可使用相对路径,或http://或https://开头,此重定向信息不可缓存,状态码:302
permanent: 重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,此重定向信息可缓存DNS解析记录(状态码后面有:from disk cache),状态码:301
break: 匹配成功后不再向下匹配,也不会跳转到其他的location,即直接结束匹配并给客户端返回结果数据
last: 对某个location的URL匹配成功后会停止当前location的后续rewrite规则,并结束当前location,然后将匹配生成的新URL跳转至其他location继续匹配,直到没有location可匹配后将最后一次location的数据返回给客户端
redirect(临时重定向)、permanent(永久重定向): 跳转型, 跳转型是指有客户端浏览器重新对新地址进行请求
break和last: 代理型,代理型是在WEB服务器内部实现跳转的。
4.1 rewrite案例--redirect与permanent:
[root@localhost7B html]# mkdir aaa bbb
[root@localhost7B html]# echo aaa.zjol.com.cn > aaa/index.html
[root@localhost7B html]# echo bbb.zjol.com.cn > bbb/index.html
#要求:因业务需要,将访问源域名 www.magedu.net 的请求永久重定向到www.magedu.com 。 临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。
server { listen 80; listen 443 ssl; server_name aaa.zjol.com.cn; ssl_certificate /usr/local/nginx/ssl/zjol2022.pem; ssl_certificate_key /usr/local/nginx/ssl/zjol2022.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; charset GB2312; location / { root /data/nginx/html/aaa; index index.html;
#域名永久重定向,京东早期的域名 www.360buy.com 由于与360公司类似,于是后期永久重定向到了 www.jd.com ,永久重定向会缓存DNS解析记录。
rewrite / https://bbb.zjol.com.cn permanent;
#域名临时重定向,告诉浏览器域名不是固定重定向到当前⽬标域名,后期可能随时会更改,因此浏览器不会缓存当 前域名的解析记录,⽽浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久重定向最⼤的本质区 别。
#rewrite / https://bbb.zjol.com.cn redirect;
} } server { listen 80; listen 443 ssl; server_name bbb.zjol.com.cn; ssl_certificate /usr/local/nginx/ssl/zjol2022.pem; ssl_certificate_key /usr/local/nginx/ssl/zjol2022.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; charset GB2312; location / { root /data/nginx/html/bbb; index index.html; } }
permanentr的测试结果, 注意有些浏览器不会显示from disk cache
redirect的测试结果
4.2 .break指令
location /rewrite3 { root /data/nginx/html/pc; index index.html; default_type text/html;
set $name magedu;
echo $name;
break; #结束循环,下面的$my_port不执行;
set $my_port $server_port; echo $my_port; }
4.2 rewrite案例--break:
1 2 3 4 | [root@localhost7B html] # mkdir break test1 test2 [root@localhost7B html] # echo break > break/index.html [root@localhost7B html] # echo test1 > test1/index.html [root@localhost7B html] # echo test2 > test2/index.html<br><br> |
server {
listen 80;
listen 443 ssl;
server_name aaa.zjol.com.cn;
ssl_certificate /usr/local/nginx/ssl/zjol2022.pem;
ssl_certificate_key /usr/local/nginx/ssl/zjol2022.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
charset GB2312;
location /break {
#return 666 "break";
root /data/nginx/html;
index index.html;
rewrite ^/break/(.*) /test1/$1 break;
#break匹配成功后不再向下匹配,也不会跳转到其他的 location,即直接结束匹配并给客⼾端返回结果数据。 $1是取regex部分第一个()里面的内容.
rewrite ^/test1/(.*) /test2/$1 break;
#break不会匹配后⾯的rewrite规则也不匹配其他 location
}
location = /test1 {
return 999 "new test1";
#index index.html;
#root /data/nginx/html;
}
location = /test2 {
return 666 "new test2";
#root /data/nginx/html;
#index index.html;
}}
测试结果
[root@localhost7D ~]# curl aaa.zjol.com.cn/break/index.html #没有匹配location = /test1和location = /test2
test1
[root@localhost7D ~]# curl aaa.zjol.com.cn/test1
new test1
[root@localhost7D ~]# curl aaa.zjol.com.cn/test2
new test2
例3: last 和 break #last适用于要不改变客户端访问方式但是需做多次目的URL重写的场景,场景不是很多。 location /last { root /data/nginx/html; index index.html; rewrite ^/last/(.*) /test3/$1 last; #last会跳转到其他的location继续匹配新的URI #arewrite ^/test3/(.*) /test4/$1 last; } location /test3 { #return 999 "new test3"; index index.html; root /data/nginx/html; rewrite ^/test3/(.*) /test4/$1 last; } location /test4 { return 666 "new test4"; #root /data/nginx/html; #index index.html; }
rewrite案例
例:将 http:// 请求跳转到 https:// location / { if ($scheme = http ) { rewrite / https://www.magedu.net/ redirect; #rewrite ^(.*)$ http://land.zzhz.zjol.com.cn/$1 permanent; #rewrite ^/(.*)$ http://land.zzhz.zjol.com.cn/$1 permanent; } } 例:要求:当用户访问到公司网站的时输入了一个错误的URL,可以将用户重定向至官网首页 location / { root /data/nginx/html/pc; index index.html; if (!-e $request_filename) { #return 404 "No exsit"; rewrite (.*) http://www.magedu.net/index.html;} } 例 http://www.magedu.com/bj --> http://www.magedu.com/beijing location /bj { rewrite ^/bj/(.*)$ /beijing/$1 last;} location /beijing { rewrite default_type text/html;}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~