测试环境说明
服务器:LuckVM 香港 CN2 节点;环境:Nginx 1.24 + PHP 8.2 + MySQL 8.0 + 宝塔面板;WordPress 版本:6.4.2
刚用宝塔装完 WordPress,一开始默认动态链接是 /?p=123 这种,能正常访问,结果一改成固定链接伪静态,点所有文章页、分类页全都是 404 Not Found,只有首页能打开。这个问题 90% 的新手装 WordPress 都会遇到,要么是 Nginx 没配伪静态规则,要么是配置没加载,要么是权限不对,这篇把我排查这个问题的完整过程记下来,遇到同样问题照着一步步查就行。
下面这张图把 WordPress 固定链接 404 的排查路径串了起来,从「先恢复默认」到「最终验证」按顺序走一遍,基本能覆盖 90% 的情况:
#mermaid-svg-1t2zNjflMQmjzsMM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1t2zNjflMQmjzsMM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1t2zNjflMQmjzsMM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1t2zNjflMQmjzsMM .error-icon{fill:#552222;}#mermaid-svg-1t2zNjflMQmjzsMM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1t2zNjflMQmjzsMM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1t2zNjflMQmjzsMM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1t2zNjflMQmjzsMM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1t2zNjflMQmjzsMM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1t2zNjflMQmjzsMM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1t2zNjflMQmjzsMM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1t2zNjflMQmjzsMM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1t2zNjflMQmjzsMM .marker.cross{stroke:#333333;}#mermaid-svg-1t2zNjflMQmjzsMM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1t2zNjflMQmjzsMM p{margin:0;}#mermaid-svg-1t2zNjflMQmjzsMM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1t2zNjflMQmjzsMM .cluster-label text{fill:#333;}#mermaid-svg-1t2zNjflMQmjzsMM .cluster-label span{color:#333;}#mermaid-svg-1t2zNjflMQmjzsMM .cluster-label span p{background-color:transparent;}#mermaid-svg-1t2zNjflMQmjzsMM .label text,#mermaid-svg-1t2zNjflMQmjzsMM span{fill:#333;color:#333;}#mermaid-svg-1t2zNjflMQmjzsMM .node rect,#mermaid-svg-1t2zNjflMQmjzsMM .node circle,#mermaid-svg-1t2zNjflMQmjzsMM .node ellipse,#mermaid-svg-1t2zNjflMQmjzsMM .node polygon,#mermaid-svg-1t2zNjflMQmjzsMM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1t2zNjflMQmjzsMM .rough-node .label text,#mermaid-svg-1t2zNjflMQmjzsMM .node .label text,#mermaid-svg-1t2zNjflMQmjzsMM .image-shape .label,#mermaid-svg-1t2zNjflMQmjzsMM .icon-shape .label{text-anchor:middle;}#mermaid-svg-1t2zNjflMQmjzsMM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1t2zNjflMQmjzsMM .rough-node .label,#mermaid-svg-1t2zNjflMQmjzsMM .node .label,#mermaid-svg-1t2zNjflMQmjzsMM .image-shape .label,#mermaid-svg-1t2zNjflMQmjzsMM .icon-shape .label{text-align:center;}#mermaid-svg-1t2zNjflMQmjzsMM .node.clickable{cursor:pointer;}#mermaid-svg-1t2zNjflMQmjzsMM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1t2zNjflMQmjzsMM .arrowheadPath{fill:#333333;}#mermaid-svg-1t2zNjflMQmjzsMM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1t2zNjflMQmjzsMM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1t2zNjflMQmjzsMM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1t2zNjflMQmjzsMM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1t2zNjflMQmjzsMM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1t2zNjflMQmjzsMM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1t2zNjflMQmjzsMM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1t2zNjflMQmjzsMM .cluster text{fill:#333;}#mermaid-svg-1t2zNjflMQmjzsMM .cluster span{color:#333;}#mermaid-svg-1t2zNjflMQmjzsMM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1t2zNjflMQmjzsMM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1t2zNjflMQmjzsMM rect.text{fill:none;stroke-width:0;}#mermaid-svg-1t2zNjflMQmjzsMM .icon-shape,#mermaid-svg-1t2zNjflMQmjzsMM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1t2zNjflMQmjzsMM .icon-shape p,#mermaid-svg-1t2zNjflMQmjzsMM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1t2zNjflMQmjzsMM .icon-shape .label rect,#mermaid-svg-1t2zNjflMQmjzsMM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1t2zNjflMQmjzsMM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1t2zNjflMQmjzsMM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1t2zNjflMQmjzsMM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 仍然 404
恢复正常
是
否
Nginx
Apache
仍然 404
已恢复
固定链接后出现 404
恢复默认动态链接
检查 PHP 版本 / 网站根目录 / Nginx 配置
是否使用宝塔面板
宝塔 → 网站 → 设置 → 伪静态 → 选 WordPress 模板并保存
Web 服务器类型
server 块内配置 try_files 规则
开启 rewrite 模块 + 检查 .htaccess 与 AllowOverride
nginx -t 校验并重载配置
重启 Apache 并验证
页面是否恢复
排查 CDN 缓存 / 插件冲突 / location 优先级 / 多站点规则
切回目标固定链接格式并最终验证
一、第一步:确认固定链接设置,先恢复默认
遇到 404 先别慌,首先去 WordPress 后台 → 设置 → 固定链接,先选「朴素」默认动态链接,点保存,看看所有页面能不能正常打开。
- 如果默认动态链接也 404:那就是 WordPress 本身没装好,或者 PHP/Nginx 配置错了,和伪静态没关系,先检查 PHP 版本、网站根目录、Nginx 配置文件对不对。
- 如果默认链接能打开,改成伪静态就 404:那 100% 是伪静态规则的问题,接着往下排查。
二、第二步:宝塔面板配置伪静态规则
用宝塔面板的话最方便,大部分情况是装完程序忘记选伪静态模板了:
- 打开宝塔面板 → 网站 → 找到你的站点 → 设置 → 伪静态
- 下拉模板选「WordPress」,面板会自动填充好规则,规则内容应该是:
location / {
try_files $uri $uri/ /index.php?$args;
}
- 点保存,这时候宝塔会自动重载 Nginx 配置,然后再刷新网站页面试试。⚠️ 坑:很多人选完模板忘了点保存,或者保存了没重载 Nginx,配置根本没生效,一定要确认保存成功。
三、第三步:手动检查 Nginx 配置(不用面板的情况)
如果没装宝塔,自己手动搭的环境,就要手动改 Nginx 配置文件:
- 找到你的站点 Nginx 配置文件,一般在
/etc/nginx/sites-available/你的站点名或者/usr/local/nginx/conf/vhost/你的域名.conf - 在 server 块里面,确保有 try_files 规则,完整的 PHP 配置应该是这样的:
server {
listen 80;
server_name 你的域名;
root /var/www/wordpress;
index index.php index.html index.htm;
# 这个就是WordPress伪静态核心规则,必须要有
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP处理配置
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
- 改完之后测试 Nginx 配置有没有语法错误:
nginx -t
# 输出test is successful才是对的,有错误会提示哪一行错了
- 重载Nginx让配置生效:
systemctl reload nginx
⚠️ 常见错误:
- 把try_files规则写在了location ~ .php块里面,根本不生效
- 根目录root路径写错了,指向了错误的文件夹
- 配置里有return 404之类的规则,把请求拦截了
四、第四步:权限和.htaccess问题排查(Apache环境)
如果你用的是 Apache 而不是 Nginx,那一般是 .htaccess 文件没生成或者权限不对:
- 先确认 Apache 开启了 rewrite 模块:
a2enmod rewrite
systemctl restart apache2
- 检查网站根目录有没有 .htaccess 文件,WordPress 固定链接保存后应该自动生成,内容是:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
- 如果没有这个文件,手动创建一个,权限设为 644,网站根目录权限设为 755,别给 777 权限,不安全。
- 检查 Apache 站点配置里 AllowOverride 是不是设成了 All,不然 .htaccess 不生效:
<Directory /var/www/wordpress>
Options Indexes FollowSymLinks
AllowOverride All # 这里必须是All,None的话.htaccess不生效
Require all granted
</Directory>
五、第五步:剩下的奇葩问题排查
如果上面三步都做了还是404,就查这几个少见的情况:
- CDN 缓存问题:如果开了 Cloudflare 或者其他 CDN,先开开发模式或者 Purge Cache,清空 CDN 缓存,可能 CDN 缓存了之前的 404 页面
- 插件冲突:把所有插件都禁用,一个个开了试,我之前遇到过缓存插件和安全插件拦截了伪静态请求,导致404
- Nginx 规则优先级问题:如果配置里有其他 location 规则(比如图片、静态文件缓存规则),要确保 try_files 的规则优先级最高,不然其他规则会先拦截请求
- 多站点配置问题:如果是 WordPress 多站点,伪静态规则和单站点不一样,要去官方文档找对应多站点的 Nginx/Apache 规则,单站点规则用在多站点上会导致子页面 404
六、最终验证
配置完之后,刷新网站,点击文章、分类、标签、分页都试试,所有页面都能正常打开之后,再去 WordPress 后台固定链接设置里选你想要的链接格式(一般选「文章名」对 SEO 最好),点保存就可以了。 我这次遇到的问题就是宝塔面板新建站点的时候,默认伪静态选的是「无」,改成 WordPress 模板保存之后立刻就恢复正常了,属于非常低级但90%新手都会踩的坑。