伪静态规则不兼容是主因,Nginx 不解析 .htaccess,必须转译为 try_files 或 if+rewrite 规则并写入 server 块;宝塔需选对模板、确认 include 生效、重启服务,并用 nginx -t 和 error.log 排查。

伪静态规则不兼容是主因,Nginx 不解析 .htaccess,必须手动转译或重写
Apache 的 .htaccess 在 Nginx 下完全失效
Apache 通过模块(mod_rewrite)在运行时逐行读取 .htaccess 文件;Nginx 没有对应机制,所有重写逻辑必须写进 server 块或独立的 include 文件中。直接把 .htaccess 放进 Nginx 目录,它既不会报错也不会执行。
- 常见错误现象:首页能打开,但点击菜单、刷新二级页面立即返回 Nginx 原生 404
- 典型场景:WordPress、ThinkPHP、Laravel、PbootCMS 等依赖 URL 重写的 PHP 程序
- 不要尝试用
include /path/.htaccess—— 这只是语法上“不报错”,实际内容仍被忽略
必须用 Nginx 语法重写 rewrite 规则
不能照搬 Apache 的 RewriteRule,需转换为 if + rewrite 或更推荐的 try_files 形式。例如原 Apache 规则:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
对应 Nginx 推荐写法(放在 location / 内):
location / {
try_files $uri $uri/ /index.php?$query_string;
}
-
try_files性能更好,避免if嵌套带来的隐式重定向开销 - 对 Laravel、ThinkPHP6 等框架,
$query_string是关键,漏掉会导致 GET 参数丢失 - PbootCMS 等老系统若坚持用
if,注意!-e $request_filename才是正确判断条件,不是!-f单独用
宝塔面板里伪静态配置容易踩的坑
宝塔提供“预设模板”,但模板不是万能解药:
- 选错模板(如给 ThinkPHP5 选了 ThinkPHP6 模板)会导致
index.php路径错位,返回 404 - 模板生成的规则若没被正确
include到当前站点配置中,等于没配——要确认配置文件里有类似include /www/server/panel/vhost/rewrite/xxx.conf; - 改完伪静态后必须点【重启】网站,只点【保存】不生效;部分 Windows 宝塔还需手动执行
"C:/BtSoft/nginx/nginx.exe" -p "C:/BtSoft/nginx/" -c "C:/BtSoft/nginx/conf/nginx.conf" -s reload - 如果用了前端 history 路由(Vue/React),还得额外加一条
location / { try_files $uri $uri/ /index.html; },和后端 PHP 的location分开写,否则会冲突
最麻烦的其实不是写错规则,而是规则写了但没生效——因为 Nginx 进程还在读旧配置,或者宝塔没把修改写进最终生效的 server 块里。遇到 404 先别急着重写,用 nginx -t 校验语法,再查 error.log 里有没有 rewrite or internal redirection cycle 这类提示,比盲目调参快得多。











