nginx中用rewrite实现.html伪静态需将指令置于server块内,推荐用location限定范围,正则需严谨并加last和qsa标志,上线前须nginx -t验证语法并开启rewrite_log调试。

在 Nginx 中,用 rewrite 实现 .html 后缀的伪静态,本质是让浏览器看到 /about.html,而服务器内部调用 /about.php(或类似动态脚本),地址栏不跳转、不暴露真实后缀。关键不在“能不能”,而在位置对不对、正则严不严、范围控不控。
rewrite 必须写在 server 块内,不能放错地方
rewrite 指令只对当前虚拟主机生效,必须嵌套在 server { ... } 花括号里:
- ✅ 正确:紧贴
location / { }上方,或放在某个特定location内部 - ❌ 错误:写在
http { }顶层 → 所有站点都会执行,极易冲突或误处理其他域名请求 - 务必确认
server_name配置准确,否则请求可能落入默认 server,规则完全不触发
推荐用 location 限定范围,避免误伤静态资源
直接在 server 级写 rewrite,容易把 /logo.png、/style.css 也匹配进去。更安全的做法是先用 location 筛选带 .html 的路径:
- 匹配所有 .html 请求:
location ~ \.html$ { rewrite ^/(.+)\.html$ /$1.php last; } - 匹配固定几个页面(更轻量):
location = /index.html { rewrite ^ /index.php last; } - 加
last表示重写后重新进入 location 匹配流程,确保能被location ~ \.php$正确转发给 PHP-FPM
正则要兼顾兼容性与安全性
常见正则陷阱会导致漏匹配或过度匹配:
- 用
^/([^?#]+)\.html$比^/([a-z]+)\.html$更稳妥:支持大小写字母、数字、下划线、中划线,也兼容多级路径(如/news/detail.html) - 务必加上
QSA标志(即rewrite ... last;后自动保留查询参数),否则/contact.html?ref=ad里的?ref=ad会丢失 - 避免无边界匹配,例如
rewrite .html /index.php last;这类写法极危险,可能匹配任意含 html 字符串的路径
上线前必须验证,别跳过这两步
配置改完不测试,等于没配:
- 运行
nginx -t检查语法是否合法,避免 reload 失败导致服务中断 - 开启
rewrite_log on;(配合error_log /path/to/log notice;),用curl -I /about.html触发请求,查看日志中 rewrite 是否按预期执行、有没有循环或空匹配 - 特别注意检查 CSS/JS 是否 404 —— 如果规则没排除静态文件后缀,它们也可能被错误重写










