nginx 伪静态通过 location ^~ /post/ 捕获请求,配合 rewrite ^/post/(\d+)(?:/.*)?$ /post.php?id=$1 last 实现内部映射,保持浏览器 url 不变;若用单入口框架,则 fallback 至 index.php。

用 Nginx 的 rewrite 实现博客文章 URL 伪静态,关键是把形如 /post/123 这样的简洁路径,内部映射到真实处理脚本(比如 /post.php?id=123),而浏览器地址栏不变。
明确匹配范围:用 location 圈定文章请求
先用 location 精准捕获文章类 URL,避免影响其他资源。推荐前缀匹配,高效且不参与正则竞争:
-
location ^~ /post/ { ... }—— 匹配所有以/post/开头的请求,如/post/456、/post/789/title - 不建议直接写
location ~ /post/,容易和其它正则 location 冲突或引发循环重写
写 rewrite 规则:提取 ID 并重写为 PHP 路径
在上述 location 块内添加 rewrite,用正则捕获文章 ID,并转成后端可执行格式:
rewrite ^/post/(\d+)(?:/.*)?$ /post.php?id=$1 last;- 说明:
(\d+)提取纯数字 ID;(?:/.*)?是非捕获组,兼容带后缀的 URL(如/post/123/my-first-post)但不参与传参;last表示重写后立即用新 URI(/post.php?id=123)重新匹配 location - 确保服务器上有能处理
.php的 location,例如:location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; ... }
兼容不存在的文件:fallback 到入口脚本(如 index.php)
如果博客用的是单入口框架(如 Typecho、WordPress),通常不单独建 post.php,而是统一走 index.php:
location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?$1 last; } }- 含义:请求的路径不是真实存在的文件或目录时,把整个原始路径作为查询参数交给
index.php(如/post/123→/index.php?/post/123) - 注意:
if在 location 中可用,但不能嵌套;last必须加,否则无法触发 PHP 处理器
验证与避坑要点
配置完别急着 reload,先检查语法并测试行为:
- 运行
nginx -t确保配置无语法错误 - 访问
/post/999,查看响应是否正常,Nginx 错误日志(/var/log/nginx/error.log)里有没有rewrite or internal redirection cycle(重写循环)报错 - 避免在 rewrite 中使用可能再次命中自身 location 的规则,例如不要写
rewrite /post/(.*) /post/$1 last; - 生产环境上线前,用 curl 测试 HTTP 状态码:伪静态应返回 200,而不是 301/302(那是真跳转,不是伪静态)











