联系QQ 284710375
首页 > 技术分享 > LNMP|WAMP
收藏

Nginx实现UrlRewrite,Nginx配置地址重定向2022-11-12 21:45:36

大潇博客 原创文章,转载请标明出处

在Nginx使用过程中,UrlRewrite是一个比较实用的功能,它可以隐藏真实的后端服务器物理地址,让url看起来直观、好记,对搜索引擎收录也比较友好


比如访问:

http://192.168.159.100/list.php?page=1

链接后面的page参数表示当前访问的第几页


想通过:

http://192.168.159.100/1.html

实现和“/list.php?page=1”一样的效果,实际“1.html”并不存在,这时可使用UrlRewrite


UrlRewrite写法:

关键字:rewrite,后面跟要访问的地址,可以精准匹配,也可以使用正则表达式模糊匹配

匹配时以“^”符号开头,以“$”符号结尾,两个符号中间写匹配规则(正则)

“$”符号后面接想要真实转发的地址,也就是要访问的真实地址,例如“/list.php?page=1”

最后面是转发的形式,有四种:break、last、redirect、permanent,用法说明如下:

  • last  本条规则匹配完成后,继续向下匹配新的location uri规则

  • break  本条规则匹配完成即中止,不再匹配后面的任何规则

  • redirect  返回302临时重定向,浏览器地址会显示跳转后的url地址

  • permanent  返回301永久重定向,浏览器地址会显示跳转后的url地址


重点可记忆为:

last和break都不会改变url地址,break优先级最高,匹配到即中止再匹配,last匹配到后还要继续往下进行匹配,直到没有可再匹配的;

redirect和permanent会改变url地址,显示效果与last和break有本质区别;

permanent的301重定向和redirect的302重定向,在用户使用时没有任何区别,都会跳转并改变地址栏的url,它们的作用是告诉网络爬虫,当前转发的新链接会不会再改变等,若是301永久重定向,爬虫记录新地址即可


格式演示:

rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结尾是flag标记,如下:

QQ图片20221112215222.png

关键字:关键字rewrite不能改变

正则:兼容常规正则表达式语句,进行规则匹配

替代内容:将正则匹配的内容替换成replacement

flag标记:rewrite支持的flag标记


注意:

1、rewrite关键字后面对uri匹配时,以斜线开头去匹配,如:^/index.html$,若想连带域名等,在斜线前加入“(.*)”,如:^(.*)/index.html$,实际没必要这样做

2、rewrite伪静态标签段的位置要在server内,location或if中


例如上面提到的两个链接,通过最简单的写法,体验一下UrlRewrite:

location / {

rewrite ^/1.html$ /list.php?page=1 break;

}

当匹配到“1.html”时,转发到“/list.php?page=1”


以上面的例子来说,实际项目中参数的值不止一个,只匹配1.html显然不现实,这样最好通过正则来模糊匹配

举个例子,通过正则匹配转发所有带数字的链接

使用中括号包起来数字,使用“+”表示至少匹配1个(换种说法:匹配1个或多个),[0-9]+

外面再用小括号包起来,表示一个UrlRewrite入参的参数组


在真实转发地址中,使用“$”符号加数字表示前面匹配到的参数,通过12345..表示顺序,例如:

location / {

rewrite ^/([0-9]+).html$ /list.php?page=$1 break;

}


location正则说明:

/ 通用匹配,任何请求都会被匹配到

= 精准匹配,不是以指定模式开头

~ 正则匹配,区分大小写

~* 正则匹配,不区分大小写匹配

^~ 非正则匹配,匹配以指定模式开头的location



拓展进阶:

1、UrlRewrite匹配规则顺序:

Nginx匹配location内的UrlRewrite规则由上而下执行,同一个location内的多条UrlRewrite规则,使用break或last标记结尾,UrlRewrite规则顺序由复杂到简单,即:匹配规则或参数较多的在上,匹配简单的在下。

举例说明,比如有这样的需求:

⑴ 访问“http://域名/news/macao/”或“http://域名/news/macao/index.html”时,转发到“http://域名/home.jsp?s=news&type=macao”;

⑵ 访问“http://域名/news/macao/index_2.html”或“http://域名/news/macao/2.html”或“http://域名/news/macao/2”时,转发到“http://域名/home.jsp?s=news&type=macao&page=2”;

⑶ 访问“http://域名/news/”或“http://域名/news/index.html”时,转发到“http://域名/home.jsp?s=news”;

⑷ 访问“http://域名/news/index_2.html”或“http://域名/news/2.html”或“http://域名/news/2”时,转发到“http://域名/home.jsp?;s=news&page=2”

⑸ 访问“http://域名/”时,转发到“http://域名/home.jsp”;

Nginx的UrlRewrite规则如下:

location / {

//首条匹配多一个规则

//以“(.*)”开始匹配,可以理解为要匹配域名,比如:“http://域名”这一段,仅次一条作为补充展示

//把举例中的“macao”换成了“(.+)”,表示可以任意匹配1至n个字符

//匹配“/news/macao/..

rewrite ^(.*)/news/(.+)/index_([0-9]+).html$  $1/home.jsp?s=news&type=$2&page=$3 last; 

rewrite ^/news/(.+)/([0-9]+).html$  /home.jsp?s=news&type=$1&page=$2 last;

rewrite ^/news/(.+)/([0-9]+)$  /home.jsp?s=news&type=$1&page=$2 last;

rewrite ^/news/(.+)/index.html$  /home.jsp?s=news&type=$1 last;

rewrite ^/news/(.+)/$  /home.jsp?s=news&type=$1 last;

//匹配“/news/..”

rewrite ^/news/index_([0-9]+).html$  /home.jsp?s=news&page=$1 last;

rewrite ^/news/([0-9]+).html$  /home.jsp?s=news&page=$1 last;

rewrite ^/news/([0-9]+)$  /home.jsp?s=news&page=$1 last;

rewrite ^/news/index.html$  /home.jsp?s=news last;

rewrite ^/news/$  /home.jsp?s=news last;

//仅域名

rewrite ^(.*)/$  /home.jsp lase;

}

仔细查看上面的条件与UrlRewrite规则,可以看到即使转发相同的地址,但rewrite匹配规则要由复杂到简单,这样也能理解“UrlRewrite规则顺序由复杂到简单”的含义


2、分组匹配

同样以上面的条件举例,我们可以发现uri都是以“/news”开头,所以我们可以在location匹配news,让代码更加清晰直观

location ~* /news {

rewrite ^(.*)/news/(.+)/index_([0-9]+).html$  $1/home.jsp?s=news&type=$2&page=$3 last; 

rewrite ^/news/(.+)/([0-9]+).html$  /home.jsp?s=news&type=$1&page=$2 last;

rewrite ^/news/index_([0-9]+).html$  /home.jsp?s=news&page=$1 last;

rewrite ^/news/([0-9]+).html$  /home.jsp?s=news&page=$1 last;

}


3、判断域名匹配

在Nginx配置文件中,“$host”可以表示当前访问的域名(只有域名,不带协议(如http://))

比如一个server段内的server_name有多个,要求uri的匹配规则相同,但转发不同

location ~* /news {

if ( $host = 'www.baidu.com' ) {

    rewrite ^(.*)/news/(.+)/index_([0-9]+).html$  $1/home.jsp?m=pc&s=news&type=$2&page=$3 last; 

}

if ( $host = 'm.baidu.com' ) {

    rewrite ^(.*)/news/(.+)/index_([0-9]+).html$  $1/home.jsp?m=wap&s=news&type=$2&page=$3 last; 

}

}


上面提到这些,熟悉后差不多能应对大部分场景

本文未完,后面想起什么我会继续补充


打赏

阅读排行

大家都在搜

博客维护不易,感谢你的肯定
扫码打赏,建议金额1-10元
  • 15601023311