Nginx 之Rewrite 使用详解
Nginx 的 rewrite
模块是处理 HTTP 请求过程中的一个重要功能,它允许基于 Perl 兼容正则表达式(PCRE)对用户请求的 URI 进行重写,并返回 30x 重定向跳转或按条件执行相关配置。
Rewrite 指令
2.1 指令语法
Nginx 中的 URL 重写主要依赖于 rewrite
指令,其基本语法如下:
rewrite <regex> <replacement> [flag];
regex:用于匹配 URI 的正则表达式。
replacement:将匹配到的 URI 替换成的新 URI。
flag(可选):控制重写的行为,常见的标志有:
last:表示重新搜索新的 location 块(即继续匹配新的规则)。
break:停止当前 location 块中的规则匹配,执行后续指令。
redirect:执行临时 重定向(302)。
permanent:执行永久重定向(301)。
2.2 Flag 标记说明
last:重写请求并继续搜索 location 匹配。
break:重写请求并停止搜索 location 匹配。
redirect:返回 302 临时重定向。
permanent:返回 301 永久重定向。
3. Rewrite 与 Location
rewrite
指令可以在 server
或 location
块中配置。location
块只对域名后除去传递参数的字符串起作用,而 rewrite
可以对域名或参数字符串进行匹配和重写。
3.1 Location 分类
普通 location:匹配特定路径。
正则 location:使用正则表达式匹配路径。
优先级:Nginx 会优先匹配带有正则表达式的 location,然后是最长非正则 location。
3.2 Rewrite 和 Location 比较
rewrite 用于重写请求 URI。
location 用于定义请求的处理方式
4. Rewrite 实际场景
4.1 基于域名的跳转
将旧域名的访问重定向到新域名,同时保持参数不变。
# 定义一个 server 块,用于处理进来的 HTTP 请求
server {
# 监听 80 端口,即 HTTP 默认端口
listen 80;
# 指定该 server 块响应的域名,这里是 olddomain.com
server_name olddomain.com;
# 定义 location 块,匹配所有 URI(/ 表示根路径)
location / {
# 使用 rewrite 指令将所有请求从 olddomain.com 重定向到 newdomain.com
# 并保持原有的请求路径和查询参数不变
rewrite ^/(.*)$ http://newdomain.com/$1 permanent;
}
}
4.2 基于客户端 IP 访问跳转
只允许特定 IP 访问,其他 IP 重定向到维护页面。
# 定义一个 server 块,用于处理进来的 HTTP 请求
server {
# 监听 80 端口,即 HTTP 默认端口
listen 80;
# 指定该 server 块响应的域名,这里是 example.com
server_name example.com;
# 定义 location 块,匹配所有 URI(/ 表示根路径)
location / {
# 使用 if 指令进行条件判断,$remote_addr 是客户端的 IP 地址
if ($remote_addr != '192.168.1.100') {
# 如果客户端 IP 地址不是 '192.168.1.100',则返回 302 状态码
# 并将请求重定向到 /maintenance.html,表示网站正在维护中
return 302 /maintenance.html;
}
}
}
这段配置的作用是限制对 example.com 的访问,只允许 IP 地址为 192.168.1.100 的客户端访问所有资源,其他所有 IP 地址的访问都会被重定向到 /maintenance.html 页面,通常用于网站维护期间。这里使用的是临时重定向(302 状态码),意味着浏览器会显示新的 URL(即 /maintenance.html),但搜索引擎和缓存可能会保留原始请求的 URL。
4.3基于最普通 URL 请求的跳转
将普通 URL 请求重写到新路径。
# 定义一个 server 块,用于处理进来的 HTTP 请求
server {
# 监听 80 端口,即 HTTP 默认端口
listen 80;
# 指定该 server 块响应的域名,这里是 example.com
server_name example.com;
# 定义 location 块,匹配所有 URI(/ 表示根路径)
location / {
# 使用 rewrite 指令进行 URL 重写
# 正则表达式 ^/(.*)$ 匹配任何以 / 开头,后面跟着任意字符的请求 URI
rewrite ^/(.*)$ /new-path/$1 permanent;
# permanent 标志表示这是一个永久重定向(301 状态码)
# 告诉浏览器和搜索引擎该资源已经被永久移动到新的位置
# $1 是正则表达式中括号内匹配到的部分,即除去第一个斜杠后的整个请求路径
}
}
这段配置的作用是将所有访问 example.com 的请求重定向到 /new-path/ 下的相同路径。例如,请求 /example.com/about 会被永久重定向到 /example.com/new-path/about
Rewrite 正则表达式
Nginx 的 rewrite 模块支持 PCRE 正则表达式,以下是一些常用的正则表达式元字符:
.:匹配任意单个字符。
^:匹配字符串的开始。
$:匹配字符串的结束。
*:匹配前面的元素 0 次或多次。
+:匹配前面的元素 1 次或多次。
?:匹配前面的元素 0 次或 1 次。
[]:匹配括号内的任意一个字符。
|:逻辑或操作符。
示例
# 第一个 server 块,用于处理对 example.com 的非 www 前缀域名的请求
server {
# 监听 80 端口,这是 HTTP 协议的默认端口
listen 80;
# 指定 server 块服务的域名,这里是 example.com(没有 www 前缀)
server_name example.com;
# 对于所有请求,返回一个 301 永久重定向响应
# 这会将用户从 http://example.com 重定向到 http://www.example.com,并保留原始请求的 URI
return 301 http://www.example.com$request_uri;
}
# 第二个 server 块,用于处理对 www.example.com 的请求
server {
# 监听 80 端口,这是 HTTP 协议的默认端口
listen 80;
# 指定 server 块服务的域名,这里是 www.example.com(带有 www 前缀)
server_name www.example.com;
# 定义 location 块,用于匹配所有请求的 URI(/ 表示根路径)
location / {
# 这里可以放置处理 www.example.com 域名请求的配置
# 例如,可以配置 proxy_pass 来代理请求,或者 root 指令来指定文件根目录等
# 正常站点配置
}
}