linux_中级_rewrite跳转

TJCcc 发布于 2025-12-24 27 次阅读


本文档基于 Rewrite.html 文件内容进行总结,并在此基础上进行了深度拓展,补充了 Nginx Rewrite 模块的核心概念、最佳实践及相关高级用法。

1. 原文档知识点总结

1.1 Rewrite 概述

  • 定义: Rewrite 主要用于实现 URL 地址重写和重定向,将请求映射到新的 URL。
  • 核心指令: rewrite regex replacement [flag]
  • 作用域: server, location, if

1.2 应用场景

  1.  地址跳转: 域名变更(如 www.lzy.com -> mobile.lzy.com)。
  2.  协议跳转: 强制 HTTP 转 HTTPS。
  3.  伪静态: 将动态 URL(如 ?id=1)转化为静态形式(如 /1.html),利于 SEO 和安全性。
  4.  SEO 优化: 缩短 URL 层级,使其更易被搜索引擎收录。

1.3 Flag 标记详解

| 标记 (Flag) | 说明 | 场景建议 |

| :--- | :--- | :--- |

| last | 停止当前 Rewrite 匹配,重新发起新一轮 Location 匹配 | 用于 Server 或 Location 区块,适用于重写后需要进一步处理的 URL |

| break | 停止当前 Rewrite 匹配,不再匹配后续规则 | 用于 Location 区块,通常用于文件路径重写,防止循环重定向 |

| redirect | 返回 302 临时重定向 | 临时维护、短链跳转(浏览器不缓存) |

| permanent | 返回 301 永久重定向 | 域名迁移、协议升级(浏览器会缓存,SEO 权重转移) |

1.4 实战案例回顾

  • 路径重写: /abc/1.html -> /ccc/bbb/2.html
  • 参数提取: /2018/ccc/2.html -> /2014/ccc/bbb/2.html (利用正则分组 $1)
  • 全站跳转: /test -> https://www.oldboy.com
  • HTTPS 强制跳转: 利用 rewrite ^(.*) https://$server_name$1 redirect
  • 条件判断: 利用 if 指令结合 $remote_addr 实现 IP 访问控制(如维护页面)。

2. 知识点深度拓展

2.1 正则表达式 (Regular Expressions) 基础

Nginx 使用 PCRE (Perl Compatible Regular Expressions) 语法。熟练掌握正则对于编写 Rewrite 规则至关重要。

| 符号 | 含义 | 示例 |

| :--- | :--- | :--- |

| ^ | 匹配字符串的开始 | ^/admin 匹配以 /admin 开头的路径 |

| $ | 匹配字符串的结束 | .html$ 匹配以 .html 结尾的路径 |

| . | 匹配除换行符以外的任意字符 | .* 匹配任意字符序列 |

| * | 重复 0 次或多次 | |

| + | 重复 1 次或多次 | |

| ? | 重复 0 次或 1 次 | |

| () | 分组捕获,用于 $1, $2 变量提取 | ^/blog/(.*)$$1 获取博客 ID |

| \ | 转义字符 | \.html 匹配实际的点号 |

| [] | 字符集合 | [a-z] 匹配任意小写字母 |

2.2 last vs break 的底层区别

这是 Nginx Rewrite 中最容易混淆的点:

  •   last: 相当于 Apache 的 [L] 标记。修改 URI 后,Nginx 会重启请求处理流程,根据新的 URI 重新匹配 location。如果配置不当,容易造成死循环(Nginx 会在 10 次循环后返回 500 错误)。
  •   break: 修改 URI 后,继续在当前 location 中执行后续指令(如 proxy_pass 或直接读取文件),不再跳出当前 location 去寻找新的匹配。

最佳实践:

  •   在 server 上下文中,通常使用 last(或者默认行为其实就是类似 last)。
  •   在 location 上下文中,如果你只是想修改文件路径并直接响应,用 break。如果你想把请求转给另一个 location 处理(比如 PHP-FPM),用 last

2.3 性能优化:rewrite vs return vs try_files

虽然 rewrite 很强大,但它是计算密集型的(需要正则引擎)。

  1.  推荐使用 return 进行重定向:

    如果你只是想做简单的 301/302 跳转,returnrewrite 更高效,因为它不需要解析正则。

    ```nginx

    # 不推荐

    rewrite ^(.*)$ https://www.example.com$1 permanent;

    # 推荐 (性能更好,可读性更强)

    return 301 https://www.example.com$request_uri;

    ```

  1.  推荐使用 try_files 处理伪静态:

    对于现代框架(Laravel, Django, ThinkPHP 等),通常不需要写复杂的正则,而是使用 try_files

    ```nginx

    # 将所有不存在的文件请求转发给 index.php

    location / {

        try_files $uri $uri/ /index.php?$query_string;

    }

    ```

    这比 rewrite ^/(.*)$ /index.php?s=$1 last; 更直观且性能略好。

2.4 常用 Nginx 内置变量补充

除了原文档列出的变量,以下变量在 Rewrite 和日志中也非常有用:

  •   $request_time: 请求处理时间(单位秒,精确到毫秒),用于性能分析。
  •   $upstream_response_time: 后端服务(如 PHP-FPM, Tomcat)响应时间。
  •   $http_referer: 来源页面,常用于防盗链配置。

    ```nginx

    valid_referers none blocked server_names *.example.com;

    if ($invalid_referer) {

        return 403;

    }

    ```

  •   $http_user_agent: 客户端浏览器标识,常用于屏蔽爬虫或针对移动端跳转。

    ```nginx

    if ($http_user_agent ~* (Scrapy|Curl|HttpClient)) {

        return 403;

    }

    ```

2.5 调试技巧

在复杂的 Rewrite 规则调试中,除了开启 rewrite_log on;,还可以使用 add_header 输出变量值到响应头,方便在浏览器或 Postman 中查看(注意:add_header 在 301/302 跳转时可能不显示)。

location /test {

    set $my_var "123";

    # 调试显示变量值

    add_header X-Debug-Var $my_var;

    add_header X-Debug-Uri $uri;

}

3. 总结

Nginx 的 Rewrite 模块是流量控制的瑞士军刀。虽然正则功能强大,但在实际生产环境中,应遵循 "简单至上" 的原则:能用 return 解决的不用 rewrite,能用 try_files 解决的不用正则。合理使用 Flag 和内置变量,可以构建出高效、安全且易于维护的 Web 服务器配置。

唯有极致沉淀,才能造就辉煌。
最后更新于 2025-12-26