rewrite规则用法和示例
1).rewrite格式: rewrite 正则 要跳转到的地址(或带域名或$request_uri) [flag]
* rewrite配置可以在server、location以及if配置段内生效
* regex是用于匹配URI的正则表达式,其不会匹配到$host(域名)
* replacement是目标跳转的URI,可以以http://或者https://开头,也可以省略掉$host(域名),直接写$request_uri部分(即请求的链接)
* flag:用来设置rewrite对URI的处理行为,其中有break、last、redirect、permanent,其中break和last在前面已经介绍过.
redirect和permanent的区别在于,前者为临时重定向(302),而后者是永久重定向(301),对于用户通过浏览器访问,这两者的效果是一致的。但是,对于搜索引擎蜘蛛爬虫来说就有区别了,使用301更有利于SEO。所以,建议replacemnet是以http://或者https://开头的flag使用permanent。建议:站外跳转用permanent,站内跳转用redirect.
2).rewrite使用示例:
示例1:
location / {
rewrite /(.*) http://www.aming.com/$1 permanent;
}
说明:.*为正则表达式,表示匹配站点根目录下链接地址,用()括起来,在后面的URI中可以调用它,第一次出现的()用$1调用,第二次出现的()用$2调用,以此类推。
示例2:
location / {
rewrite /.* http://www.aming.com$request_uri permanent;
}
说明:在replacement中,支持变量,这里的$request_uri就是客户端请求的链接
示例3:
server{
listen 80;
server_name www.123.com;
root /tmp/123.com;
index index.html;
rewrite /(.*) /abc/$1 redirect;
}
说明:匹配站点中任何地址时候,都会跳转一下,增加一级/abc目录,一直循环跳转,本例中的rewrite规则有问题,会造连续循环,最终会失败,解决该问题有两个方案。
关于循环次数,经测试发现,curl 会循环50次,chrome会循环80次,IE会循环120次,firefox会循环20次。
禁止循环的解决方法1: break
server{
listen 80;
server_name www.123.com;
root /tmp/123.com;
index index.html;
rewrite /(.*) /abc/$1 break;
}
说明:在rewrite中使用break,会避免循环。
禁止循环的解决方法2:正则匹配,当匹配到站点地址里有不是/abc时候,再跳转,当有/abc时候则不跳转。
$request_uri就是客户端请求的链接。
server{
listen 80;
server_name www.123.com;
root /tmp/123.com;
index index.html;
if ($request_uri !~ '^/abc/')
{
rewrite /(.*) /abc/$1 redirect;
}
}
说明:加一个条件限制,也可以避免产生循环
3).rewrite示例实战
a).常用示例:
域名跳转(域名重定向):
示例1(不带条件的):
server{
listen 80;
server_name www.aminglinux.com;
rewrite /(.*) http://www.aming.com/$1 permanent;
#permanent也算是301跳转,(.*)括号括起来是为了让后面$1引用,访问站点跟目录所有跳转到另一个域名,
.......
}
示例2(带条件的):
server{
listen 80;
server_name www.aminglinux.com aminglinux.com;
if ($host != 'www.aminglinux.com') #当$host主机头(也就是域名)不是该域名时候跳转
{
rewrite /(.*) http://www.aminglinux.com/$1 permanent;
}
.......
}
示例3(http跳转到https):
server{
listen 80;
server_name www.aminglinux.com;
rewrite /(.*) https://www.aminglinux.com/$1 permanent;
.......
}
示例4(域名访问二级目录)
server{
listen 80;
server_name bbs.aminglinux.com;
rewrite /(.*) http://www.aminglinux.com/bbs/$1 last; #last是跳转后就中断,不让循环跳转,只让跳转一次,也可break
.......
}
示例5(静态请求分离)当访问地址带相应静态资源时候,会跳转到另一域名
下面的location等价于$uri,都是表示客户端访问的地址(域名+地址)
server{
listen 80;
server_name www.aminglinux.com; #另一个未备案域名在国外解析(访问静态资源有点慢,可跳转到国内备案网站)
location ~* ^.+.(jpg|jpeg|gif|css|png|js)$ #当访问地址里带图片或js等静态资源时候,跳转到另一个域名网站(如国内网站)
{
rewrite /(.*) http://img.aminglinux.com/$1 permanent;
}
.......
}
或者:
server{
listen 80;
server_name www.aminglinux.com;
if ( $uri ~* 'jpg|jpeg|gif|css|png|js$') #当访问地址带相应静态资源时候,会跳转到另一域名,*表示不区分大小写
{
rewrite /(.*) http://img.aminglinux.com/$1 permanent;
}
.......
}
防盗链:
盗链网站概念和防倒链设置
正常情况下: 正规网站提供资源: 访问正规网站如www.baidu.com访问图片等资源,能访问到,是正常情况。
盗用情况: 搭建倒链网站www.daolian.com,建立能链接到正规网站资源的代码地址,使得客户访问我倒链网站时候,我自己不能提供给客户资源,通过链接到正规网站后把正规网站的资源,如图片给客户。相当于盗用了正规网站的资源。
防盗链设置: 在正规网站中设置防盗链,不是白名单的域名不能访问资源,即:访问倒链的网站地址则不能访问到资源。
示例6
server{
listen 80;
server_name www.aminglinux.com;
location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$ #访问的地址里包含这些资源时候,,*表示不区分大小写
{
valid_referers none blocked server_names *.aminglinux.com aminglinux.com *.aming.com aming.com; #定义合法域名
if ($invalid_referer) #如果域名不合法,不让访问资源,即:访问倒链网站则不提供资源
{
rewrite /(.*) http://img.aminglinux.com/images/forbidden.png;
}
}
.......
}
说明:
*这里是通配,跟正则里面的*不是一个意思,none指的是referer不存在的情况(curl -e 测试),
blocked指的是referer头部的值被防火墙或者代理服务器删除或者伪装的情况,即:referer头部的值不以http://或者https://开头(curl -e 后面跟的referer不以http://或者https://开头)。
或者:
location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$ #访问的地址里包含这些资源时候,*表示不区分大小写
{
valid_referers none blocked server_names *.aminglinux.com *.aming.com aminglinux.com aming.com; #定义合法域名
if ($invalid_referer) #如果域名不合法,不让访问资源,即:访问倒链网站则不提供资源
{
return 403; #如果域名不合法,不让访问资源,即:访问倒链网站则不提供资源
}
}
伪静态:(了解,需要根据程序员需求来写)
示例7(discuz伪静态):
location / {
rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last;
rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last;
rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last;
rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last;
rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last;
rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3 last;
}
rewrite多个条件的并且:(了解)
示例8:
应用场景:当请求地址同时满足多个条件时候才做rewrite跳转,下面是:当请求地址是以/abc开头,且是ie浏览器或火狐浏览器时候才做rewrite跳转。通过先设置一个变量,rule=0,然后满足第一个条件后,设置rule=01,在满足第2个条件时候,设置rule=012,则如果rule的值是012,则证明同时满足了两个条件,就可以做rewrite跳转了。
location /{
set $rule 0; #先设置rule=0
if ($document_uri !~ '^/abc')
{
set $rule "${rule}1"; #当满足第一个条件,以/abc开头时候,设置rule=01
}
if ($http_user_agent ~* 'ie6|firefox')
{
set $rule "${rule}2"; #当满足第二个条件,火狐或ie浏览器,设置rule=012
}
if ($rule = "012") #若rule=012,则表示两个条件都满足了,再做rewrite跳转。
{
rewrite /(.*) /abc/$1 redirect;
}
}
b).常用示例中有疑问的详解:
静态请求分离:当访问地址带相应静态资源时候,会跳转到另一域名:
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
include vhost/*.conf;
[root@localhost ~]# vim /usr/local/nginx/conf/vhost/www.aminglinux.conf
server{
listen 80;
server_name www.aminglinux.com;
root /data/wwwroot/www.com;
index index.html;
location ~* ^.+.(jpg|jpeg|gif|css|png|js)$ #当访问地址带相应静态资源时候,会跳转到另一域名
{
rewrite /(.*) http://img.aminglinux.com/$1 permanent;
}
}
配置文件也可写成:
[root@localhost ~]# cat /usr/local/nginx/conf/vhost/www.aminglinux.conf
server{
listen 80;
server_name www.aminglinux.com;
root /data/wwwroot/www.com;
index index.html;
if ( $uri ~* 'jpg|jpeg|gif|css|png|js$') #当访问地址带相应静态资源时候,会跳转到另一域名
{
rewrite /(.*) http://img.aminglinux.com/$1 permanent;
}
}
[root@localhost ~]# mkdir /data/wwwroot/www.com -p
[root@localhost ~]# echo index > /data/wwwroot/www.com/index.html
[root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload
[root@localhost ~]# curl www.aminglinux.com
index
[root@localhost ~]# curl www.aminglinux.com/abc/abc.png -I #当访问地址带相应静态资源时候,会跳转到另一域名
HTTP/1.1 301 Moved Permanently
Server: nginx/1.15.9
Date: Sun, 20 Dec 2020 01:43:47 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: http://img.aminglinux.com/abc/abc.png