URL 重写(Rewrite)
Nginx 的 **URL 重写(Rewrite)**功能允许你根据请求的 URL 动态地修改请求路径或进行重定向。通过 URL 重写,你可以实现诸如:
- 友好 URL:将复杂的 URL 转换为简洁、易记的形式。
- 301/302 重定向:实现页面永久或临时重定向。
- 条件重写:基于不同的条件(如请求头、IP 地址、用户代理等)修改请求路径。
本文将详细介绍如何在 Nginx 中实现 URL 重写,并给出一些常见的实际场景。
Nginx 中的 URL 重写指令
Nginx 中的 URL 重写主要依赖于两个指令:
rewrite
:用于修改请求的 URL。try_files
:尝试一系列的文件路径,并在文件不存在时重写 URL。
rewrite 指令
rewrite 指令允许你根据正则表达式重写 URL。其基本语法如下:
rewrite <匹配规则> <重写目标> [标志];
-
匹配规则:正则表达式,匹配请求的 URL。
-
重写目标:新的 URL,符合规则时,Nginx 会将请求的 URL 重写为这个目标。
-
标志(可选):控制重写的行为,常见的标志有:
-
last
:表示重新搜索新的 location 块(即继续匹配新的规则)。 -
break
:停止当前 location 块中的规则匹配,执行后续指令。 -
redirect
:执行临时重定向(302)。 -
permanent
:执行永久重定向(301)。
-
这里举个例子:
rewrite ^/archive/(\d{4})/(\d{2})/(\d{2})$ /archive?year=$1&month=$2&day=$3 last;
可以分解为:
^/archive/(\d{4})/(\d{2})/(\d{2})$
:这是一个正则表达式,表示匹配/archive/
后跟着年份、月份和日期的 URL。具体匹配:^
表示匹配 URL 的开始;/archive/
是固定的路径部分;(\d{4})
匹配 4 位数字(年份);(\d{2})
匹配 2 位数字(月份);(\d{2})
匹配 2 位数字(日期);$
表示匹配 URL 的结尾。
/archive?year=$1&month=$2&day=$3
:这是重写后的目标 URL。这里使用了捕获组的替换:$1
被替换为第一个捕获组(即年份)。$2
被替换为第二个捕获组(即月份)。$3
被替换为第三个捕获组(即日期)。- 最终重写的 URL 是
/archive?year=2024&month=03&day=25
。
last
:这个标志表示 Nginx 会停止当前的rewrite
匹配,并继续重新匹配请求的新 URL(即/archive?year=2024&month=03&day=25
)。
首先来看这部分正则表达式:
(\d{4})/(\d{2})/(\d{2})
。
(\d{4})
:
\d
是一个正则表达式元字符,表示匹配 数字字符,即 0-9 的任意数字。{4}
是量词,表示前面的表达式(这里是\d
)必须出现 4 次。- 因此,
(\d{4})
匹配 4 位数字,通常用来表示年份(比如 2024)。/(\d{2})
:
- 同理,
(\d{2})
匹配 2 位数字,通常用来表示月份(如03
)或日期(如25
)。- 这里的
\d{2}
匹配的是 2 个数字,表示月份或日期。/(\d{2})
:
- 这个部分与上面相同,匹配的是 2 位数字,通常表示日期部分。
综合起来:
(\d{4})/(\d{2})/(\d{2})
就是用来匹配像/2024/03/25
这样的 URL,具体来说:
- 第一部分
(\d{4})
匹配年份部分(例如 2024)。- 第二部分
(\d{2})
匹配月份部分(例如 03)。- 第三部分
(\d{2})
匹配日期部分(例如 25)。
()
作用:括号
()
用来 捕获匹配的内容。捕获的内容可以通过$1
,$2
,$3
来引用。这是正则表达式中的“捕获组”(capture groups)。在示例中,
(\d{4})
、(\d{2})
和(\d{2})
就是捕获组,分别捕获年份、月份和日期。
$1
、$2
、$3
是什么意思?在正则表达式中,捕获组(即
()
中匹配的内容)会按顺序赋予数字标识。
$1
:引用第一个捕获组(这里是(\d{4})
),即年份部分。$2
:引用第二个捕获组(这里是(\d{2})
),即月份部分。$3
:引用第三个捕获组(这里是(\d{2})
),即日期部分。假设请求的 URL 是
/archive/2024/03/25
,在rewrite
指令中,(\d{4})
将捕获到2024
,(\d{2})
捕获到03
,另一个(\d{2})
捕获到25
。
$1
就是2024
(第一个捕获组)。$2
就是03
(第二个捕获组)。$3
就是25
(第三个捕获组)。
try_files 指令
try_files 用于检查一系列文件是否存在,如果文件存在则继续处理,否则进行 URL 重写。它常用于静态资源的处理,例如检查文件是否存在,如果不存在,则重写请求到某个页面(通常是首页或错误页面)。
try_files <文件1> <文件2> ... <重写目标>;
常见的 URL 重写场景
实现 301/302 重定向
当你需要将旧 URL 重定向到新 URL 时,rewrite
指令非常有用。301 是永久重定向,告诉搜索引擎这个页面已经被永久移动;302 是临时重定向,表示页面将暂时被移动到新的 URL。
示例:将 http://example.com/old-page
重定向到 http://example.com/new-page
server { listen 80; server_name example.com; location /old-page { rewrite ^/old-page$ /new-page permanent; } location /new-page { # 处理新页面的配置 } }
配置解释:
rewrite ^/old-page$ /new-page permanent;
:将/old-page
重定向到/new-page
,并使用永久重定向(301)。permanent
标志表示这是一个永久性重定向。
将非 www 域名重定向到 www 域名
如果你希望所有请求都通过 www.example.com
访问,可以使用 Nginx 重定向非 www 域名的请求。
示例:将 example.com
重定向到 www.example.com
server { listen 80; server_name example.com; # 进行 301 重定向 return 301 http://www.example.com$request_uri; } server { listen 80; server_name www.example.com; location / { # 正常的站点配置 } }
配置解释:
return 301 http://www.example.com$request_uri;
:将所有example.com
的请求重定向到www.example.com
,并保留请求的 URI。
URL 正则重写:简化 URL 结构
你可以使用正则表达式对 URL 进行重写,使 URL 更加简洁、符合 SEO 标准。
示例:将 /category/id/123
重写为 /category/123
server { listen 80; server_name example.com; location /category/id/ { rewrite ^/category/id/(\d+)$ /category/$1 last; } }
配置解释:
rewrite ^/category/id/(\d+)$ /category/$1 last;
:将/category/id/123
重写为/category/123
,并使用last
标志继续匹配新的location
块。
动态 URL 重写:参数化查询
如果你的网站 URL 需要支持动态查询参数,可以使用 rewrite
指令根据 URL 参数进行重写。
示例:将 /search?q=keyword
重写为 /search/keyword
server { listen 80; server_name example.com; location /search { rewrite ^/search\?q=(\w+)$ /search/$1 last; } }
配置解释:
rewrite ^/search\?q=(\w+)$ /search/$1 last;
:将/search?q=keyword
重写为/search/keyword
,并使用last
标志继续匹配新的location
块。
404 页面重定向
当请求的文件或页面不存在时,你可能希望将请求重定向到一个自定义的 404 页面或者首页。可以通过 try_files
指令实现。
示例:当请求的文件不存在时,重定向到 index.html
server { listen 80; server_name example.com; location / { try_files $uri $uri/ /index.html; } }
配置解释:
try_files $uri $uri/ /index.html;
:Nginx 将首先检查请求的文件是否存在,如果不存在,则将请求重写为/index.html
。
结合正则表达式进行动态 URL 重写
Nginx 支持强大的正则表达式匹配功能,可以用来处理更复杂的 URL 重写需求。以下是一个更复杂的 URL 重写示例,结合条件和正则表达式来进行动态路由。
示例:根据日期重写 URL
server { listen 80; server_name example.com; location /archive/ { rewrite ^/archive/(\d{4})/(\d{2})/(\d{2})$ /archive?year=$1&month=$2&day=$3 last; } }
配置解释:
- rewrite ^/archive/(\d{4})/(\d{2})/(\d{2})$ /archive?year=$1&month=$2&day=$3 last;:将 /archive/2024/03/25 重写为 /archive?year=2024&month=03&day=25。
以上就是在Nginx中实现URL重写与重定向的详细内容,更多关于Nginx URL重写与重定向的资料请关注恩蓝小号其它相关文章!
原创文章,作者:MLGGY,如若转载,请注明出处:http://www.wangzhanshi.com/n/19315.html