Nginx伪静态核心是rewrite指令精准匹配路径参数并拼接query string,需正则捕获、保留$query_string、用last标志,优先try_files替代if,配合日志调试验证。
核心是用 rewrite 指令匹配路径中的结构化参数,再拼成带 query string 的后端目标地址,而不是真生成静态文件。关键在正则捕获、保留原始查询参数、选对 flag,并避免滥用 if。
URL 重写只处理 URI 路径部分(不含域名和 ? 后的查询字符串),所以规则要精准匹配路径格式:
rewrite ^/article/(d+).html$ /article.php?id=$1 last;匹配 /article/123.html,把 123 捕获为 $1,转发给 /article.php?id=123
rewrite ^/p/([a-zA-Z0-9_]+)$ /index.php?p=$1 last;支持 slug 类型 ID,如 /p/about-us → /index.php?p=about-us
^ 和 $ 表示严格起止,防止误匹配;last 表示重写后重新匹配 location,适合多数伪静态场景如果用户访问的是 /article/123.html?from=wechat&utm_source=news,默认重写会丢掉这些参数。需手动保留:
rewrite ^/article/(d+).html$ /article.php?id=$1&$query_string last;$query_string 是 Nginx 内置变量,原样包含 ? 后所有内容(不含 ? 号本身),所以拼接时要加 &
? 开头拼接,否则可能覆盖原有参数或引发双重问号问题很多教程用 if (!-f $request_filename) { rewrite ... } 实现“找不到静态文件就转 PHP”,但 if 在 location 块中行为复杂、易出错。更稳妥的方式是:
location / { try_files $uri $uri/ /index.php?$query_string; }try_files 先检查文件/目录是否存在,不存在才 fallback 到 index.php,同时透传全部原始参数if 的作用域陷阱配置完别急着 reload,先确认是否生效:
rewrite_log on;(需配合 error_log /path/to/error.log notice;)curl -I http://localhost/article/456.html,观察响应头是否为 200,后端是否收到 id=456