Nginx 基础配置中 rewrite 重写规则如何编写

作者:袖梨 2026-08-13

Nginx rewrite规则本质是用正则匹配请求URI并改写路径,必须置于server或location块内,按顺序执行,依赖标志位(last/break/redirect/permanent)控制流程与匹配行为。

Nginx 的 rewrite 规则本质是用正则匹配请求 URI,再按规则跳转或改写路径。它不复杂,但容易因匹配顺序、标志位或上下文位置出错。

rewrite 写在哪?位置很关键

rewrite 必须放在 serverlocation 块里,不能直接写在 http 块顶层。不同位置行为不同:

  1. 写在 server 块中:对所有进入该虚拟主机的请求,在 location 匹配前统一处理
  2. 写在 location 块中:只对匹配到该 location 的请求生效,且重写后会重新进行 location 匹配(除非加 last
  3. 避免在 if 块里滥用 rewrite(Nginx 最新不推荐),尤其不要在 if 中做非变量判断(如 if ($request_uri ~* ...)

基本语法和常用标志位

格式为:rewrite 正则 替换串 标志;

  1. 正则:匹配 $request_uri(不含域名和参数,含开头斜杠),建议用 ^/old/(.*)$ 这类锚定写法,避免误匹配
  2. 替换串:可引用捕获组($1, $2),也可拼接新路径,如 /new/$1
  3. 标志位
    1. last:重写后停止当前 location 处理,用新 URI 重新匹配 location(常用)
    2. break:重写后不再匹配其他 rewrite,也不重新 location 查找(适合内部路径改写)
    3. redirect:返回 302 临时跳转(加 https:// 或完整 URL 才生效)
    4. permanent:返回 301 永久跳转

常见实用场景写法

例如把 /article/123 改成 /post?id=123

rewrite ^/article/(d+)$ /post?id=$1? last;

注意结尾的 ? 可清空原始 query string,避免变成 /post?id=123?old=param

  1. 去掉路径末尾斜杠:rewrite ^(.*[^/])/$ $1 permanent;
  2. 强制 HTTPS 跳转:rewrite ^(.*)$ https://$host$1 permanent;(需配合 if ($scheme != "https") 使用,但更推荐用 return 301
  3. 隐藏 .php 扩展名:rewrite ^/(.*).php$ /$1 last;,再配合 try_files $uri.php $uri =404;

调试和避坑提示

rewrite 不生效?先检查这几项:

  1. 确认正则是否真正匹配(可用在线 regex 工具测试,注意 Nginx 默认 PCRE,^$ 锚定整个 URI)
  2. 查看 error log,开启 error_log /path/to/log warn;,rewrite 失败或循环会报 rewrite or internal redirection cycle
  3. 多个 rewrite 按书写顺序执行,前面的可能影响后面的匹配,必要时用 break 截断
  4. 静态文件路径重写后,确保后续 location 能正确命中(比如重写成 /static/xxx.png,就得有对应 location /static/

相关文章

精彩推荐