目录
前言
一、Nginx Rewrite的概述
1.Nginx Rewrite跳转场景
2.Rewrite跳转实现
3.Nginx跳转需求的实现方式
二、location的分类
1.分类
2.常用匹配规则
3.location优先级
4.比较rewrite和location
5.rewrite会写在location里,执行顺序
二、Nginx Rewrite的操作方式
1.基于域名的跳转
2、基于客户端IP访问跳转
3.基于旧域名跳转到新域名后面加目录
4.基于参数匹配(多余)的跳转
5.基于目录下所有 php 结尾的文件跳转
6.基于最普通一条 url 请求的跳转
总结
Nginx的跳转更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的Apache 服务器,虽然也能做跳转,规则库也很强大,但是用Nginx 跳转效率会更高。
为了让URL看起来更规范、合理
企业会将动态URL地址伪装成静态地址提供服务
网址换新域名后,期望用户可以通过旧的访问跳转到新的域名上
服务端某些业务调整
Nginx:通过ngx_http_rewrite_module模块支持URL重写、支持if条件判断,但不支持else
跳转:从一个location跳转到另一个location,循环最多可以执行10次,超过后nginx将返回500错误
PCRE支持:perl兼容正则表达式的语法规则匹配
重写模块set指令:创建新的变量并为其赋值
使用rewrite进行匹配跳转
使用if匹配全局变量后跳转
使用location匹配再跳转
精准匹配:location = / {…}
一般匹配:location / {…}
正则匹配:location ~ / {…}
符号 | 描述 |
---|---|
= | 进行普通字符精准匹配,也就是完全匹配 |
^~ | 表示普通字符匹配,使用前缀匹配;如果匹配成功,则不再匹配后续location |
~ | 区分大小写的匹配 |
~* | 不区分大小写的匹配 |
!~ | 区分大小写的匹配取非 |
!~* | 不区分大小写的匹配取非 |
相同类型的表达式,字符串长的会优先匹配
1.首先精准匹配 =
2.其次前缀匹配 ^~
3.其次是按文件中顺序的正则匹配 ~ 或 ~*
4.然后是匹配不带任何修饰的前缀匹配,即一般匹配
5.最后交给 / 通用匹配,优先级最低
1、location = / {}
= 为精确匹配 /,主机名后面不能带任何字符串,比如访问 / 和 /data,则 / 匹配,/data 不匹配
再比如 location = /abc,则只匹配 /abc,/abc/或 /abcd不匹配。若 location /abc ,则即匹配/abc、/abcd/ 同时也匹配/abc/。
2、location / {} www.kgc.com/路径
因为所有的地址都以/开头,所以这条规则将匹配到所有请求比如访问/和/data, 则/匹配,/data 也匹配,
但若后面是正则表达式会和最长字符串优先匹配(最长匹配)
3、location /documents/ {}
匹配任何以/documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它location
只有其它location后面的正则表达式没有匹配到时,才会采用这一条
4、location /documents/abc {}
匹配任何以/documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它location
只有其它location后面的正则表达式没有匹配到时,才会采用这一条
5、location ^~ /images/ {}
匹配任何以/images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条
6、location ~* \. (gif|jpg|jpeg)$ {}
匹配所有以gif、jpg或jpeg结尾的请求
然而,所有请求/images/下的图片会被location ^~ /images/ 处理,因为^~的优先级更高,所以到达不了这一条正则
7、location /images/abc {}
最长字符匹配到/images/abc,优先级最低,继续往下搜索其它location, 会发现^~和~存在
8、location ~ /images/abc {}
匹配以/images/abc开头的,优先级次之,只有去掉location ^~ /images/ 才会采用这一条
9、location /images/abc/1.html {}
匹配/images/abc/1.html文件,如果和正则location ~ /images/abc/1.html相比,正则优先级更高
相同点 | 都能实现跳转 |
不同点 | rewrite是同一域名内更改获取资源的路径 location是一类路径做控制访问或反向代理,还可以proxy_pass到其他机器 |
执行server块里面的rewrite指令
执行location匹配
执行选定的location中的rewrite指令
例:现在公司旧域名www.kgc.com有业务需求变更,需要使用新域名www.zch.com代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。
[root@localhost ~]# mkdir -p /var/log/nginx/ #创建日志目录
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
...
server {
listen 80;
server_name www.kgc.com; #域名修改
charset utf-8;
access_log /var/log/nginx/www.kgc.com-access.log; #开启并对日志保存路径进行修改
location / {
if ($host = 'www.kgc.com'){ #$host为rewrite全局变量,代表请求主机头字段或主机名
rewrite ^/(.*)$ http://www.zch.com/$1 permanent; #$1为匹配的位置变量,即域名后边得字符串,同时永久跳转
}
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
...
[root@localhost ~]# systemctl restart nginx.service
此时访问 http://www.kgc.com 时会自动跳转到 www.zch.com 上进行访问。同时可以访问www.kgc.com在显示错误页面的同时可以看到域名也会变化为www.zch.com
例:今天公司业务新版本上线,要求所有 IP 访问任何内容都显示一个固定维护页面,只有公司 IP 192.168.196.146访问正常。
[root@localhost ~]# mkdir -p /var/log/nginx/
[root@localhost ~]# mkdir -p /var/www/html
[root@localhost ~]# echo '页面维护中...
' > /var/www/html/weihu.html
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
...
server {
listen 80;
server_name www.zch.com;
charset utf-8;
access_log /var/log/nginx/www.zch.com-access.log; #设置是否是合法的IP标记
set $rewrite true; #设置变量$rewrite,变量形式为布尔值为true
if ($remote_addr = "192.168.196.146") { #判断是否为合法IP
set $rewrite fasle;
}
if ($rewrite = true) { #除了合法IP,其它都是非法IP,进行重写跳转到维护页面
rewrite (.+) /weihu.html; #重写在访问IP后边插入/weihu.html,例如192.168.196.146/weihu.html
}
location = /weihu.html {
root /var/www/html; #页面返回/var/www/html/weihu.html的内容
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
...
[root@localhost ~]# systemctl restart nginx.service
此时用另外一台机子访问192.168.196.146时会跳转到weihu.html界面,而只有IP为192.168.196.146的机子才可以正常进行访问。
当访问的是 http://www.kgc.com/post/1.html 会自动跳转到 http://www.zch.com/bbs/post/1.html
[root@localhost ~]# mkdir -p /var/log/nginx/
[root@localhost ~]# mkdir -p /usr/local/nginx/html/bbs/post
[root@localhost ~]# echo "this is 1.html
" >> /usr/local/nginx/html/bbs/post/1.html
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
...
server {
listen 80;
server_name www.kgc.com;
charset utf-8;
access_log /var/log/nginx/www.kgc.com-access.log;
location /post {
rewrite (.+) http://www.zch.com/bbs$1 permanent;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
...
[root@localhost ~]# systemctl stop nginx
[root@localhost ~]# systemctl start nginx
[root@localhost ~]# mkdir -p /var/log/nginx/
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
...
server {
listen 80;
server_name www.zch.com;
charset utf-8;
access_log /var/log/nginx/www.zch.com-access.log;
if ($request_uri ~ ^/100-(100|200)-(\d+)\.html$) {
rewrite (.*) http://www.zch.com permanent;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
...
[root@localhost ~]# systemctl restart nginx.service
要求访问 http://www.zch.com/upload/123.php 跳转到首页www.zch.com(常用场景:网站新用户提示需要注册)
[root@localhost ~]# mkdir -p /var/log/nginx/
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
...
server {
listen 80;
server_name www.zch.com;
charset utf-8;
access_log /var/log/nginx/www.zch.com-access.log;
location ~* /upload/.*\.php$ {
rewrite (.*) http://www.zch.com permanent;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
...
[root@loaction ~]# systemctl restart nginx.service
浏览器访问 http://www.zch.com/admin/159.html 跳转到 http://www.zch.com 首页。
[root@localhost ~]# mkdir -p /var/log/nginx/
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
...
server {
listen 80;
server_name www.zch.com;
charset utf-8;
access_log /var/log/nginx/www.zch.com-access.log;
location ~* /admin/159.html {
rewrite (.+) http://www.zch.com permanent;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
...
[root@loaction ~]# systemctl restart nginx.service
匹配具体文件:(location = 完整路径) > (location ^~ 完整路径) > (location ~* 完整路径) > (location ~ 完整路径) > (location 完整路径) > (location /)
目录做匹配访问:(location = 目录) > (location ^~ 目录/) > (location ~ 目录) > (location ~*目录) > (location 目录) > (location /)