Nginx—Rewrite

目录

一、Nginx---Rewrite概述

1、常用的Nginx正则表达式

2、Rewrite功能

3、Rewrite跳转实现

4、Rewrite执行顺序和语法格式

二、location概述

1、location分类

[2、location 常用的匹配规则](#2、location 常用的匹配规则)

[3、location 优先级](#3、location 优先级)

案例一:

案例二:

案例三:

案例四:

案例五:

案例六:

案例七:

案例八:

案例九:

[三、Nginx 常见网站配置示例](#三、Nginx 常见网站配置示例)

3.1、网站根目录匹配规则

3.2、静态文件处理规则

3.3、动态请求转发规则

[四、Rewrite 案例](#四、Rewrite 案例)

1、基于域名的跳转

[2、基于客户端 IP 访问跳转](#2、基于客户端 IP 访问跳转)

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

4、基于参数匹配的跳转

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

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


一、Nginx---Rewrite概述

1、常用的Nginx正则表达式

|----|--------------|
| ^ | 匹配输入字符串的起始位置 |

|---|--------------|
| $ | 匹配输入字符串的结束位置 |

|----|--------------|
| * | 匹配前面的字符零次或多次 |

|---|--------------|
| + | 匹配前面的字符一次或多次 |

|---|--------------|
| ? | 匹配前面的字符零次或一次 |

|---|--------------------|
| . | 匹配除 \n 之外的任何单个字符 |

|----|-------------------------|
| \ | 转义字符,使后面的字符被视为普通字符或特殊字符 |

|-----|-------------------|
| \d | 匹配数字(相当于 [0-9]) |

|-----|---------------|
| {n} | 匹配前面的字符恰好 n 次 |

|------|---------------|
| {n,} | 匹配前面的字符至少 n 次 |

|-------|----------------------|
| {n,m} | 匹配前面的字符至少 n 次,至多 m 次 |

|------|--------------------|
| [] | 定义字符集,匹配括号内的任意单个字符 |

|-------|----------|
| [c] | 匹配单个字符 c |

|---------|--------------|
| [a-z] | 匹配小写字母中的任意一个 |

|---------------|--------------|
| [a-zA-Z0-9] | 匹配所有大小写字母或数字 |

|----|---------------|
| () | 组括号,分组和捕获子表达式 |

2、Rewrite功能

①、使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。

  • 比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。

②、rewrite只能放在server{},location{},if{}中,并且默认只能对域名后边的除去传递的参数外的字符串起作用,

3、Rewrite跳转实现

ngx_http_rewrite_module 模块

  • 支持 URL 重写和条件判断。
  • 通过 if 指令支持条件判断,但不支持 else

URL 跳转

  • 可以在 location 块中使用 rewrite 指令实现从一个 location 跳转到另一个 location
  • 跳转循环最多执行 10 次,超过 10 次会导致 Nginx 返回 500 错误。

PCRE 支持

  • 支持 Perl 兼容正则表达式(PCRE)语法规则进行匹配。

set 指令

  • 用于创建新的变量并设定其值。

4、Rewrite执行顺序和语法格式

①、执行顺序:

执行 server 块中的 rewrite 指令

  • server 块中定义的 rewrite 指令首先被执行,用于处理请求。

执行 location 匹配

  • 根据请求的 URI,Nginx 会匹配最合适的 location 块。

执行选定的 location 中的 rewrite 指令

  • 在匹配到的 location 块中,执行该块内定义的 rewrite 指令。

②、语法格式:

cpp 复制代码
rewrite <regex> <replacement> [flag];

regex

  • 表示用于匹配请求 URL 的正则表达式规则。

  • replacement

    • 表示 URL 重写后的目标内容或路径。

flag(可选):

  • 用于指定重写的标志,影响重写操作的行为。

常见标志包括:

  • last:停止当前 location 的匹配过程,重新选择合适的 location
  • break:停止当前 location 的匹配过程,并继续执行当前 location 中的其他指令。
  • redirect:发出一个临时的 302 重定向响应。
  • permanent:发出一个永久的 301 重定向响应。

二、location概述

1、location分类

①、精准匹配

  • 语法:location = / {...}
  • 说明:严格匹配指定的 URI,只有当请求的 URI 完全匹配时,才会应用该 location 块中的配置。

②、一般匹配

  • 语法:location / {...}
  • 说明:前缀匹配,请求的 URI 以指定的前缀开头时会匹配该 location 块。适用于大多数简单的 URI 匹配情况。

③、正则匹配

  • 语法:location ~ /regex {...}
  • 说明:使用正则表达式进行匹配,适用于复杂的 URI 匹配场景。正则匹配会在一般匹配后进行。

2、location 常用的匹配规则

匹配规则 说明 示例
= 精确匹配 URI,URI 必须完全匹配时才应用 location = /yudh { ... }
^~ 普通字符前缀匹配,匹配成功后停止其他 location 匹配 location ^~ /images/ { ... }
~ 区分大小写的正则表达式匹配 location ~ .jpg$ { ... }
~* 不区分大小写的正则表达式匹配 location ~* .jPg$ { ... }
!~ 区分大小写的正则表达式匹配取非 location !~ .jpg$ { ... }
!~* 不区分大小写的正则表达式匹配取非 location !~* .jPg$ { ... }

3、location 优先级

  • 首先精确匹配 =
  • 其次前缀匹配 ^~
  • 其次是按文件中顺序的正则匹配 ~或~*
  • 然后匹配不带任何修饰的前缀匹配 abc
  • 最后是交给 / 通用匹配 /

案例一

cpp 复制代码
location = /http://www.kgc.com/data {
    # 配置
}
location = /abc {
    # 配置
}

案例二:

cpp 复制代码
location / {
    # 配置
}

比如有以下三个地址:

因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 比如访问 / 和 /data, 则 / 匹配,/data 也匹配。但若后面是正则表达式会和最长字符串优先匹配(最长匹配)

案例三:

cpp 复制代码
location /documents/ {
    # 配置
}

比如有以下一个地址:

它匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它 location;只有其它 location后面的正则表达式没有匹配到时,才会采用这一条。

案例四:

cpp 复制代码
location /documents/abc {
    # 配置
}

匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它 location;只有其它 location后面的正则表达式没有匹配到时,才会采用这一条。

案例五:

cpp 复制代码
location ^~ /images/ {
    # 配置
}

匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。

案例六:

cpp 复制代码
location ~* \.(gif|jpg|jpeg)$ {
    # 配置
}

匹配所有以 gif、jpg或jpeg 结尾的请求,然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则。

案例七:

cpp 复制代码
location /images/abc {
    # 配置
}

最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在。

案例八:

cpp 复制代码
location ~ /images/abc {
    # 配置
}

匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条。

案例九:

cpp 复制代码
location /images/abc/1.html {
    # 配置
}
location ~ /images/abc/1.html {
    # 配置
}

匹配/images/abc/1.html 文件,如果和正则location ~ /images/abc/1.html 相比,正则优先级更高

优先级总结:

cpp 复制代码
(location = 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (location /)

location 匹配顺序:

  • 首先看 优先级:精确>前缀>正则>一般>通用
  • 优先级相同:正则看上下顺序,上面的优先;一般匹配看长度,最长匹配的优先
  • 精确、前缀、正则、一般 都没有匹配到,最后再看通用匹配 一般匹配

三、Nginx 常见网站配置示例

在实际网站的 Nginx 配置中,通常至少会定义三个匹配规则,以实现高效的请求处理。这些规则包括首页的匹配规则、静态文件的处理规则,以及动态请求的转发规则。

3.1、网站根目录匹配规则

这个规则用于直接匹配网站的根目录(/),通常用于访问网站首页。因为通过域名访问网站首页的请求较为频繁,使用这个规则可以加速处理。首页可以是一个静态页面,也可以转发到后端应用服务器。

cpp 复制代码
location = / {
    root   html;
    index  index.html index.htm;
}

解释 :当请求 URI 为 / 时,Nginx 会寻找 html 目录下的 index.htmlindex.htm 作为首页响应。如果有必要,这个请求也可以被转发到后端服务器进行处理。

3.2、静态文件处理规则

Nginx 作为 HTTP 服务器,处理静态文件请求是其强项。可以通过目录匹配或后缀匹配来处理静态资源请求,任选其一或搭配使用。

目录匹配 :匹配以 /static/ 开头的请求,将其映射到文件系统的 /webroot/static/ 目录。

cpp 复制代码
location ^~ /static/ {
    root /webroot/static/;
}

后缀匹配 :匹配特定后缀的请求,如 .html.gif.jpg 等,将这些请求映射到文件系统的 /webroot/res/ 目录。

cpp 复制代码
location ~* \.(html|gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}

解释:目录匹配主要用于静态资源的路径匹配,后缀匹配则用于对特定类型文件的请求匹配。根据实际需求,可以选择一种或两种方式组合使用。

3.3、动态请求转发规则

对于非静态文件的请求,通常会默认认为是动态请求,这类请求需要转发到后端应用服务器进行处理。例如,将带有 .php.jsp 后缀的请求转发给 Tomcat 等后端服务器。

cpp 复制代码
location / {
    proxy_pass http://tomcat_server;
}

解释 :这个通用规则将所有未匹配到前面规则的请求(即大多数动态请求)转发到后端应用服务器 http://tomcat_server 进行处理。

四、Rewrite 案例

1、基于域名的跳转

在某些情况下,可能需要将旧域名的所有请求重定向到新域名,并且保持 URL 中的参数不变。以下是一个 Nginx 配置示例,用于将旧域名 www.kgc.com 的请求永久重定向到新域名。

编辑 Nginx 配置文件

cpp 复制代码
vim /usr/local/nginx/conf/nginx.conf

设置 Nginx 服务器块

cpp 复制代码
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 ^/(.*)$ http://www.benet.com/$1 permanent;     //将旧域名的请求重定向到新域名,保持参数不变
        }
        root   html;
        index  index.html index.htm;
    }
}

更新 /etc/hosts 文件

cpp 复制代码
echo "172.16.88.22 www.kgc.com www.benet.com" >> /etc/hosts

重启 Nginx 服务并测试

cpp 复制代码
systemctl reload nginx

在浏览器中访问旧域名,如 http://www.kgc.com/test/1.html,你将会看到页面自动跳转到 http://www.benet.com/test/1.html,并且浏览器的开发者工具中会显示返回的 301 状态码,表示实现了永久重定向。

2、基于客户端 IP 访问跳转

在某些情况下,可能需要根据客户端的 IP 地址来控制对网站的访问。例如,新的业务版本上线期间,所有的访问都需要跳转到维护页面,只有特定的公司 IP 地址可以正常访问网站。以下是 Nginx 的配置示例,用于实现这个需求。

首先,打开 Nginx 的主配置文件 nginx.conf 并进行编辑

cpp 复制代码
vim /usr/local/nginx/conf/nginx.conf

在配置文件中,添加如下的 server 块配置,用于处理旧域名的请求并将其重定向到新域名。

cpp 复制代码
server {
    listen       80;
    server_name  www.kgc.com;    //设置域名

    charset utf-8;
    access_log  /var/log/nginx/www.kgc.com-access.log;    //设置访问日志

    //设置 IP 访问控制变量
    set $rewrite true;     //默认所有 IP 需要重定向到维护页面

    # 判断是否为合法 IP 地址
    if ($remote_addr = "172.16.88.22") {  //如果客户端 IP 为 172.16.88.22
        set $rewrite false;  //不进行重写,允许正常访问
    }

    //对于非法 IP 地址进行重写跳转
    if ($rewrite = true) {    //如果变量 $rewrite 仍为 true
        rewrite (.+) /weihu.html;  //重定向到维护页面
    }

    //配置维护页面的 location
    location = /weihu.html {
        root /var/www/html;  //设置维护页面文件所在目录
    }

    //配置正常访问的 location
    location / {
        root   html;  //设置正常网站的根目录
        index  index.html index.htm;
    }
}

/var/www/html/ 目录下创建一个简单的维护页面

cpp 复制代码
mkdir -p /var/www/html/
echo "<h1>We are maintaining now!</h1>" > /var/www/html/weihu.html

重启 Nginx 服务并测试

cpp 复制代码
systemctl restart nginx
  • 访问网站时,只有 IP 为 172.16.88.22的用户 能够正常访问网站的内容。
  • 其他所有 IP 的访问请求都会被重定向到 /weihu.html 维护页面,并显示维护信息 We are maintaining now!

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

当旧域名需要重定向到新域名的特定路径时,可以使用 Nginx 的 rewrite 指令进行配置。以下是如何将旧域名 http://bbs.kgc.com/post/ 下的所有请求跳转到新域名。

打开 Nginx 的主配置文件 nginx.conf 并进行编辑

cpp 复制代码
vim /usr/local/nginx/conf/nginx.conf

在配置文件中,添加如下的 server 块配置,用于处理旧域名的重定向

cpp 复制代码
server {
    listen       80;
    server_name  bbs.kgc.com;    //旧域名

    charset utf-8;
    access_log  /var/log/nginx/www.kgc.com-access.log;    //设置访问日志

    //设置旧域名下 /post 的重定向规则
    location /post {
        rewrite ^/post(.*)$ http://www.kgc.com/bbs/post$1 permanent;  //进行永久重定向
    }

    //配置其他请求的处理
    location / {
        root   html;
        index  index.html index.htm;
    }
}

在新域名的对应路径下创建一个测试文件

cpp 复制代码
mkdir -p /usr/local/nginx/html/bbs/post
echo "this is 1.html" > /usr/local/nginx/html/bbs/post/1.html

修改本地 hosts 文件,为了在本地测试,将旧域名映射到本地服务器的 IP 地址

cpp 复制代码
echo "172.16.88.22 bbs.kgc.com" >> /etc/hosts

重启 Nginx 服务并测试

cpp 复制代码
systemctl restart nginx

在浏览器中访问 http://bbs.kgc.com/post/1.html。你应该会被重定向到http://www.kgc.com/bbs/post/1.html。这表明重定向规则已经成功应用,并且旧域名的请求被正确地转发到了新域名下的相应路径。

4、基于参数匹配的跳转

在实际应用中,有时需要根据特定的 URL 参数模式将用户请求重定向到其他页面。下面是如何使用 Nginx 的 rewrite 指令实现这样的需求:将访问 http://www.kgc.com/100-(100|200)-100.html 的请求重定向到 http://www.kgc.com 首页。

打开 Nginx 的主配置文件 nginx.conf 并进行编辑:

cpp 复制代码
vim /usr/local/nginx/conf/nginx.conf

在配置文件中,添加如下的 server 块配置,用于处理基于参数匹配的跳转:

cpp 复制代码
server {
    listen       80;
    server_name  www.kgc.com;    //域名设置

    charset utf-8;
    access_log  /var/log/nginx/www.kgc.com-access.log;     //设置访问日志

    # 设置基于参数匹配的跳转规则
    if ($request_uri ~ ^/100-(100|200)-(\d+).html$) {
        rewrite (.+) http://www.kgc.com permanent;    //重定向到首页
    }

    # 配置其他请求的处理
    location / {
        root   html;
        index  index.html index.htm;
    }
}
  • $request_uri:表示包含请求参数的原始 URI,不包含主机名。
  • if ($request_uri ~ ^/100-(100|200)-(\d+).html$):匹配 URL 中符合 100-100-100.html100-200-100.html 模式的请求。
  • rewrite (.+) http://www.kgc.com permanent;:将符合条件的请求永久重定向到 http://www.kgc.com 首页。

重启 Nginx 服务并测试

cpp 复制代码
systemctl restart nginx

使用浏览器访问以下链接:

  • http://www.kgc.com/100-100-100.html
  • http://www.kgc.com/100-200-100.html

两者均应被重定向到 http://www.kgc.com 首页,表明 Nginx 已成功匹配并重定向请求。

Nginx 相关变量解释

  • $request_uri :包含原始请求 URI 和参数(如 /abc/bbs/index.html?a=1&b=2)。
  • $uri :仅包含请求的路径部分,不包含参数(如 /abc/bbs/index.html)。
  • **document_uri** :与 `uri` 相同,表示当前请求的路径部分,不包含参数。

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

在某些情况下,可能需要将访问特定目录下所有以 .php 结尾的文件请求重定向到网站首页。以下是如何在 Nginx 中配置这类跳转的详细步骤。

首先,打开 Nginx 的主配置文件 nginx.conf 进行编辑:

cpp 复制代码
vim /usr/local/nginx/conf/nginx.conf

在配置文件中,添加如下的 server 块,用于处理对特定目录下 .php 文件的重定向:

cpp 复制代码
server {
    listen       80;
    server_name  www.kgc.com;  # 设置域名

    charset utf-8;
    access_log  /var/log/nginx/www.kgc.com-access.log;  # 设置访问日志

    # 配置对 /upload/ 目录下所有 .php 文件的跳转
    location ~* /upload/.*\.php$ {
        rewrite (.+) http://www.kgc.com permanent;  # 将匹配的请求永久重定向到首页
    }
    
    # 配置其他请求的处理
    location / {
        root   html;
        index  index.html index.htm;
    }
}
  • location ~* /upload/.*\.php$:该行定义了对 /upload/ 目录下所有以 .php 结尾的文件进行正则匹配,~* 表示不区分大小写。
  • rewrite (.+) http://www.kgc.com permanent;:将符合条件的请求永久重定向到 http://www.kgc.com 首页。

重启 Nginx 服务并测试重定向

cpp 复制代码
systemctl restart nginx

使用浏览器访问以下链接:

  • http://www.kgc.com/upload/123.php

请求将被重定向到 http://www.kgc.com 首页,表明 Nginx 已成功匹配并重定向请求。

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

在一些场景中,可能需要将访问特定页面的请求重定向到网站的首页。以下是如何在 Nginx 中配置这类 URL 请求跳转的详细步骤。

首先,打开 Nginx 的主配置文件 nginx.conf 进行编辑

cpp 复制代码
vim /usr/local/nginx/conf/nginx.conf

在配置文件中,添加如下的 server 块,用于处理对特定 URL 的重定向:

cpp 复制代码
server {
    listen       80;
    server_name  www.kgc.com;    //设置域名

    charset utf-8;
    access_log  /var/log/nginx/www.kgc.com-access.log;    //设置访问日志

    //配置对 /abc/123.html 页面请求的跳转
    location ~* ^/abc/123.html {
        rewrite (.+) http://www.kgc.com permanent;  //将匹配的请求永久重定向到首页
    }

    //配置其他请求的处理
    location / {
        root   html;
        index  index.html index.htm;
    }
}
  • location ~* ^/abc/123.html:该行定义了对具体 URL /abc/123.html 进行匹配,~* 表示不区分大小写。
  • rewrite (.+) http://www.kgc.com permanent;:将符合条件的请求永久重定向到 http://www.kgc.com 首页。

重启 Nginx 服务并测试重定向

cpp 复制代码
systemctl restart nginx

使用浏览器访问以下链接:

  • http://www.kgc.com/abc/123.html

请求将被重定向到 http://www.kgc.com 首页,表明 Nginx 已成功匹配并重定向请求。

相关推荐
okok__TXF3 分钟前
Nginx + Lua脚本打配合
nginx·lua
良许Linux9 分钟前
0.96寸OLED显示屏详解
linux·服务器·后端·互联网
青灯文案110 分钟前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
ThisIsClark13 分钟前
【后端面试总结】MySQL主从复制逻辑的技术介绍
mysql·面试·职场和发展
蜜獾云19 分钟前
docker 安装雷池WAF防火墙 守护Web服务器
linux·运维·服务器·网络·网络安全·docker·容器
小屁不止是运维21 分钟前
麒麟操作系统服务架构保姆级教程(五)NGINX中间件详解
linux·运维·服务器·nginx·中间件·架构
Hacker_Oldv25 分钟前
WPS 认证机制
运维·服务器·wps
bitcsljl34 分钟前
Linux 命令行快捷键
linux·运维·服务器
ac.char37 分钟前
在 Ubuntu 下使用 Tauri 打包 EXE 应用
linux·运维·ubuntu
Python之栈1 小时前
【无标题】
数据库·python·mysql