Nginx-rewrite重写规则

457 阅读8分钟
  • 掌握rewrite重写规则
  • 熟悉使用rewrite flag
  • 掌握其中的状态码301,302
  • 熟悉案例
  • PV,UV,独立IP

Nginx 重写 (rewrite) 是一个强大的功能,它允许你修改请求的 URI (统一资源标识符)。通过使用 rewrite 指令,你可以将请求的 URL 重定向到新的 URL,通常用于 URL 美化、301/302 重定向或将旧的 URL 指向新的 URL。

基本语法

rewrite <regex> <replacement> [flag];
  • <regex>: 正则表达式,用于匹配请求的 URI。
  • <replacement>: 替换字符串,用于生成新的 URI。
  • [flag]: 可选的标志,可以是 lastbreakredirectpermanent 等。

示例

1. 简单重写

将所有对 example.com/old 的请求重定向到 example.com/new

server {
    listen 80;
    server_name example.com;

    location /old {
        rewrite ^/old$ /new redirect;
    }
}

2. 301 永久重定向

如果你想要一个 301 永久重定向,可以使用 permanent 标志。

server {
    listen 80;
    server_name example.com;

    location /old {
        rewrite ^/old$ /new permanent;
    }
}

3. 使用正则表达式提取参数

从 URL 中提取参数并传递到新 URL。

server {
    listen 80;
    server_name example.com;

    location /user/ {
        rewrite ^/user/(.*)$ /profile.php?user=$1 last;
    }
}

常用标志

  • last: 停止当前请求处理,并继续处理新的请求。
  • break: 停止处理当前 rewrite 规则,并继续处理当前 location 的其他匹配。
  • redirect: 返回临时重定向状态 (302)。
  • permanent: 返回永久重定向状态 (301)。

注意事项

  • rewrite 指令不应在 location 块内再使用新的 rewrite 指令,因为它可能会导致循环重定向。
  • 尽量静态化路径而不是使用复杂的重写规则,以提高性能。

以上是 Nginx 重写的基础知识和一些示例,你可以根据自己的需求来修改和使用这些规则。

案例一

  1. 配置准备
  2. 本地host解析域名地址为自己的服务器
server {
        listen 80;
        server_name test.oldboy.com;
        root /code/test/;

        location / {
        rewrite /1.html /2.html;
        rewrite /2.html /3.html; 
        }

        location /2.html {
        rewrite /2.html /a.html;
        }

        location /3.html {
        rewrite /3.html /b.html;
        }
}
  1. 页面准备
mkdir /code/test
echo 22222 > /code/test/2.html
echo 33333 > /code/test/3.html
echo aaaaa > /code/test/a.html
echo bbbbb > /code/test/b.html
  1. 跳转过程
    1. 当client通过浏览器访问test.oldboy.com时,根据location的匹配规则先匹配到第一个location,而第一个location中先执行第一个rewrite,接着顺序执行第二个rewrite,最终URL将被重定向到/3.html,客户端对/3.html重新发起请求,然后继续重定向到b.html,客户端会继续重新向服务器请求最终响应/b.html
    2. 当client访问test.oldboy.com/2.html时,根据匹配规则,会优先选择路径匹配到第二个location,后续的访问过程一致。

注意:重定向的过程并非是在服务器内部完成的,重定向的过程通常是客户端重新向新的 URL 发起请求

案例展示: image.png

image.png

image.png

  1. 进一步探究rewrite中last,break的作用 在 Nginx 的 rewrite 和 location 配置中,lastbreak 是两个重要的指令,它们影响请求的处理流程,具体区别如下:

last

  • last 指令告诉 Nginx 结束当前的 rewrite 规则并开始新的请求处理阶段。
  • 一旦使用了 last,Nginx 将重新寻找与当前请求 URI 匹配的 location 块。
  • 适用于想要在处理请求时执行完全不同的 location 或规则。

示例:

rewrite ^/oldpath/(.*)$ /newpath/$1 last;

在这个示例中,请求 http://example.com/oldpath/foo 将被重新定向到 http://example.com/newpath/foo,并在此基础上重新寻找适用的 location。

break

  • break 指令用于终止当前 location 的处理,而不是将请求转发到下一个 location。
  • Nginx 会继续处理当前 location 块中的剩余指令,但不会去寻找其他 location。
  • 常用于在特定条件下立即停止进一步的处理,但仍希望在这个 location 内部执行其他指令。

示例:

break

  • 使用 break 时,当执行到该 rewrite 指令后,Nginx 将停止继续执行后续的 rewrite 指令,但会继续执行当前 location 块中的其他指令。
  • 如果当前 location 中没有其他指令,将会执行新的请求匹配,即按新的 URL 重新匹配 location

last

  • 使用 last 时,当执行到该 rewrite 指令后,Nginx 将立即停止执行当前 location 块中的其他指令,并重新开始匹配 location。这是相当于用重写后的 URL 来进行新的请求匹配。

示例解析

以示例为例:

location / {
    rewrite /1.html /2.html break;
    rewrite /2.html /3.html; 
}
  • 客户端请求 /1.html,重写为 /2.html 并停在 break,后续的rewrite并不会执行,并且后续也没有其他指令,所以将重新匹配location。

而在下面的例子中:

location / {
    rewrite /1.html /2.html last;
    rewrite /2.html /3.html; 
}
  • 客户端请求 /1.html,重写为 /2.html,然后因为使用了 last,这时 Nginx 会重新开始匹配新的 URL /2.html,所以会根据 URL 决定匹配哪个 location,而不会继续执行下一行的 rewrite 指令。

总结

  • break:停止当前处理,继续执行其他除rewrite以外的指令。
  • last:停止当前处理,并重新开始匹配 location

案例二

在 Nginx 中,rewrite 指令可用于 URL 重写和重定向。使用状态码 301 和 302 进行重定向时,具体含义如下:

  1. 301 Moved Permanently

    • 表示请求的资源已被永久移动到新位置。
    • 该状态码会被搜索引擎记录,从而更新索引,指向新的 URL。
    • 一般用于永久性重定向。
    • 只请求一次源地址

    示例:

    location / {
        rewrite ^/old-path(.*)$ /new-path$1 permanent;  # 发送 301 重定向
    }
    
  2. 302 Found (或 302 Moved Temporarily)

    • 表示请求的资源临时移动到新位置。
    • 搜索引擎通常不会更新索引,仍然认为原 URL 是有效的。
    • 一般用于临时重定向。
    • 每次都会请求源地址

    示例:

    location / {
        rewrite ^/temp-old(.*)$ /temp-new$1 redirect;  # 发送 302 重定向
    }
    

如何选择

  • 选择 301:如果你确定 URL 会永久更改,使用 301。这对于 SEO 有益,可以帮助搜索引擎更新其索引。
  • 选择 302:如果你只是在做临时更改,保持原地址的有效性时,使用 302。

总结

  • 两种状态码的主要区别在于重定向是临时的还是永久的。
  • 对于大多数后续请求和 SEO 考虑,选择合适的状态码非常重要。

实操

server {
        listen 80;
        server_name   test.oldboy.com;
        root /code;

        location /test {
                rewrite ^(.*)$  http://www.baidu.com redirect;	# 临时跳转
                #return 302 http://www.oldboy.com;	# 临时跳转
                
                #return 301 http://www.oldboy.com;	# 永久跳转
                #rewrite ^(.*)$  http://www.oldboy.com permanent;   # 永久跳转       
        }
}

image.png

image.png

http状态码描述信息
200OK
301永久跳转
302临时跳转
304缓存
307内部跳转
401验证没有通过
403有目录没资源
404没有代码目录
502坏的网关,数据库无响应
503负载过高
504数据库超时,无法连接

案例三

用户访问/abc/1.html实际上真实访问的是/ccc/bbb/2.html

server {
        listen 80;
        server_name   test.oldboy.com;
        root /code;

        location /abc {
           rewrite ^(.*)$  /ccc/bbb/2.html;
        }
}

image.png

用户访问/2018/ccc/2.html实际上真实访问的是/2014/ccc/bbb/2.html

server {
        listen 80;
	server_name test.oldboy.com;
        location / {
                root /code;
                index index.html;
        }
        location /2018 {
                rewrite ^/2018/(.*)$ /2014/$1 redirect;
        }
}
mkdir /code/2014/test/ -p
echo 2014.... > /code/2014/test/1.html
echo 2.... > /code/2014/test/2.html
echo 3.... > /code/2014/test/3.html

image.png

访问course-11-22-33.html实际上访问/course/11/22/33/course_33.html

server {
        listen 80;
	server_name test.oldboy.com;
        root /code;
        index index.html;
        location / {
        #灵活配法
        rewrite ^/course-(.*)-(.*)-(.*).html$ /course/$1/$2/$3/course_$3.html redirect;
        #固定配法
        #rewrite ^/course-(.*) /course/11/22/33/course_33.html redirect;
        }
}

维护页面配置

server {
    listen 80;
    server_name test.oldboy.com;
    root /code;
    charset utf-8,gbk;

    location / {
        index index.html;
        set $ip 0;       # 设置变量为0
        if ($remote_addr = "10.0.0.1"){
            set $ip 1;   # 如果来源IP为0.1则设置为1
        }
        if ($ip = 0){    # 判断如果变量为0 则跳转维护页面
            rewrite ^(.*)$ /wh.html break;
        }
    }

}

image.png

image.png

在网络和网站分析中,PV(Page View)、UV(Unique Visitor)和独立IP是常用的指标,下面是它们的定义及区别:

PV(Page View 页面浏览量)

  • PV指的是网页被访问的次数。每当一个用户加载一个页面,无论是同一用户重复访问还是不同用户访问,都会计入一次PV。
  • 例如,如果一个用户在同一次访问中浏览了三个不同的页面,那么PV将会增加三次。

UV(Unique Visitor 独立访客)

  • UV衡量的是在特定时间段内唯一的访客数量。它通常通过用户的IP地址或者用户的cookie来进行统计。
  • 例如,如果同一个用户在一天内多次访问该网站,按照UV的计算方法,该用户只会被计入一次。

独立IP

  • 独立IP是指访问网站的不同IP地址数量。在某些情况下,独立IP可以作为评估访客数量的替代指标。
  • 需要注意的是,多个用户可能会通过同一个IP地址(例如通过公司网络或家庭网络共享连接)访问网站,因此独立IP可能并不完全等同于UV。

总结

  • PV是总的页面浏览次数,反映了访问量的多少。
  • UV是独立访客数,反映了有多少个独立个体在访问。
  • 独立IP数是指访问该网站的不同IP地址数量,用于衡量用户访问的分散度。

这些指标共同帮助网站管理员分析网站的流量和用户行为,为决策提供数据支持。

示例

PV: 点击的数量,打开网站算一个PV,刷新1次算1个PV。点击里面任意文章累加1个PV 每个用户访问京东大概得PV是多少? 20个PV 每个用户小说访问大概得PV是多少? 一章(一页)就是一个PV

UV: 一台硬件设备为一个UV,一个UV一个用户。

独立IP: 出口IP,公网IP地址 可以独立算出一个网站的大概得PV UV和独立IP地址。 学校---->独立公网IP出去上网
比例公司100个人--->独立IP1个 100个人有几个人访问京东--->就算几个硬件设备--->UV的数量

30万PV UV? 计算每个硬件设备点击的数量*UV=30万PV 京东: 300000/100=3000UV 独立的IP: 3000/5-10比例 = 300 -1000之间独立公网IP地址。

100万PV?