Nginx Rewrite

一、Nginx Rewrite概述

        现在 Nginx 已经成为很多公司作为前端反向代理服务器的首选,在实际工作中往往会遇到很多跳转(重写 URL)的需求。比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的Apache服务器,虽然也能做跳转,规则库也很强大,但是用Nginx跳转效率会更高,这也是学习本章的目的所在。

1.Rewrite跳转场景

        Rewrite跳转场景主要包括以下几种:
        可以调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求。
        为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
        网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的 360buy.com 会跳转到 jd.com。
        根据特殊变量、目录、客户端的信息进行 URL 调整等。

2.Rewrite跳转实现

        Nginx 是通过 ngx_http_rewrite_module 模块支持 url 重写、支持if条件判断,但不支持 else。另外该模块需要 PCRE 支持,应在编译 Nginx 时指定 PCRE 支持,默认已经安装根据相关变量重定向和选择不同的配置,从一个location 跳转到另一个location,不过这样的循环最多可以执行 10 次,超过后 Nginx 将返回 500 错误。同时,重写模块包含 set 指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。rewrite 功能就是使用 Nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 ur 重写以及重定向。

3.Rewrite实际应用场景

        在实际工作的应用中,Nginx跳转需求有三种方式可实现。可以直接用rewite 进行匹配跳转,也可以使用if匹配全局变量后跳转。另外,还可以使用location 匹配再跳转。所以rewrite 只能放在 server{}、f{}、location{}配置段中。例如 location 只能对域名后边的除去传递的参数外的字符串起作用,例如 http:/www.kgc.com/index.php?id=1只对fndex.php 重写。如果想对域名或参数字符串起作用,可以使用if全局变量匹配,也可以使用proxy_pass反向代理。 

4.Nginx正则表达式 

        以下是常用正则表达式元字符。

二、Nginx Rewrite基本操作

1.Rewrite语法 

        Rewrite 命令的语法如下所示,其中regex 表示正则匹配规则、replacement 表示跳转后的内容、fag 表示 rewrite 支持的 fag 标记。

rewrite<regex><replacement>[flag];

        flag 标记说明:
        last:相当于 Apache 的[L]标记,表示完成 rewrite。
        break:本条规则匹配完成即终止,不再匹配后面的任何规则。
        redirect: 返回 302临时重定向,浏览器地址会显示跳转后的 URL地址,爬虫不会更新url(因为是临时)。
        permanent:返回 301永久重定向,浏览器地址栏会显示跳转后的 URL地址,爬虫更新 url。

        如果后面不跟 flag 标记,那么默认是 302 临时重定向。在实际工作场景中,还有另一种 return 指定。因为 301 和 302不能简单的只返回状态码,还必须有重定向的 URL,这就是 return 指令无法返回 301 和 302 的原因。
        last 和 break 区别是: last 一般写在 server 和if中,而 break 一般使用在 location 中。last 不终止重写后的 url 匹配,即新的 url 会再从 server 走一遍匹配流程,而 break 终止重写后的匹配。

2.Location分类 

       location 大致可以分为三类,语法如下:

location = patt {}[精准匹配]
location patt {}[一般匹配]
location ~ patt {}[正则匹配]

        精准匹配和一般匹配不需要做详细的说明,主要是正则匹配。下面就是正则匹配的一些表达式,需要多加牢记。
        ~:表示执行一个正则匹配,区分大小写。
        ~*:表示执行一个正则匹配,不区分大小写。
        !~:表示执行一个正则匹配,区分大小写不匹配。
        !~":表示执行一个正则匹配,不区分大小写不匹配。
        ^~:表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location。
        >=:进行普通字符精确匹配,也就是完全匹配。
        @:它定义一个命名的 location,使用在内部定向时,例如 error_page, try_files。

3.Location优先级 

        在 Nginx 的 location 配置中 location 的顺序没有太大关系。匹配优先级和 location 表达式的类型有关:相同类型的表达式,字符串长的会优先匹配。
        以下是按优先级排列说明:
        等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。
        ^~类型表达式。一旦匹配成功,则不再查找其他匹配项。
        正则表达式类型(~和~*)的优先级次之。
        常规字符串匹配类型。按前缀匹配。
        通用匹配(/),如果没有其它匹配,任何请求都会匹配到。
        从功能看 rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获取资源的路径,而location 是对一类路径做控制访问或反向代理,还可以proxy_pass 到其他机器。很多情况下rewrite 也会写在 location 里,它们的执行顺序如下:
        (1)执行 server 块里面的 rewrite 指令。
        (2)执行 location 匹配。
        (3)执行选定的 location 中的 rewrite 指令。 

        现在,对 location 优先级进行总结。 
        如果是匹配某个具体文件:
        (location= 完整路径)>(location^~ 完整路径)>(location ~*完整路径)>(location~完整路径)>(location 完整路径)>(location /) 
        如果是用目录做匹配访问某个文件:
(location= 目录)>(location^~ 目录/)>(location~ 目录)>(location~*目录)>(location 目录)>(location /)

4.Rewrite常见示例

(1)基于域名的跳转 

        假如,现在公司旧域名www.benet.com有业务需求变更,需要使用新域名www.accp.com 代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。在Nginx配置文件里的 location / 下面添加如下内容。

if ($host = 'www.benet.com') {
    rewrite ^/(.*)$ http://www.accp.com/$1 permanent;
}

(2)基于客户端IP访问跳转

        例如今天公司业务版本上线,要求所有IP访问任何内容都显示一个固定维护页面,只有公司 IP 访问正常。在Nginx配置文件里添加如下内容。

set $rewrite true,
if ($remote addr="192.168.10.101"){
    set $rewrite false,
}
if ($rewrite = true){
    rewrite (.+)/aaa.html;
}
location = /aaa.html {
    root /usr/local/nginx/html;
}

(3)基于旧域名跳转到新域名后面加目录

        例如现在访问的是 http://bbs.benet.com,现在需要将这个域名下面的发帖都跳转到http://www.benet.com/bbs,注意保持域名跳转后的参数不变。在Nginx配置文件里修改如下内容。

server name    bbs.kgc.com;
location /post {
    rewrite (.+)http:/www.kgc.com/bbs$1 permanent;
}

 (4)基于参数匹配的跳转

        例如现在访问 http:/www.benet.com/100-(100-200)-(任何数字).html跳转到 http://www.benet.com页面。在/etc/nginx/conf.d/default.conf文件里添加如下内容。

if($request uri ~ ^/100-(1[0-9][0-9])-(\d+).html$){
    rewrite (.*) http://www.kgc.com permanent;
}

(5)基于目录下所有php结尾的文件跳转

        要求访问http:/www.benet.com/upload/1.php跳转到首页。在Nginx配置文件里添加如下内容。

location ~* /upload/.*\.php$ {
    rewrite (.+) http://www.benet.com permanent;
}

 (6)基于最普通一条url请求的跳转

        要求访问一个具体的页面跳转到首页,在Nginx配置文件里添加如下内容。

location ~* ^/1/test.html {
    rewrite (.+) http://www.kgc.com permanent;
}

 

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值