WordPress 404 与伪静态失效处理
先判断这个 404 是谁发的
「首页能开,内页全 404」是最常见的一类求助。它可能发生在刚改完固定链接、刚搬完服务器、刚配完 CDN 之后,也可能什么都没做就突然出现。处理这类问题的关键不是背配置,而是先分清这个 404 是 Nginx 发出的、Apache 发出的,还是 WordPress 主题自己渲染的 404 页——这三种来源对应三套完全不同的修法。
六种 404 场景
看范围就能猜到大半
故障范围是第一个线索。只有内页 404、只有分页 404、只有某一种语言版本 404,指向的原因完全不同。
首页正常,所有内页 404
最典型。首页走的是 index.php,不需要重写规则;内页依赖「把 /product/abc/ 转给 index.php」这一步。规则缺失或未生效,就只有首页能开。九成出在 .htaccess 或 Nginx 的 try_files。
改完固定链接立刻全站 404
在「设置 → 固定链接」里从「朴素」改成「文章名」之后,如果没有触发规则重写,旧链接全部失效。正常情况下保存时 WordPress 会自动 flush,但文件不可写时就静默失败。
- 表现:后台正常,前台全 404
- 先看 .htaccess 是否可写
只有分页和搜索 404
/page/2/、/?s=关键词 打不开,文章页正常。多半是规则里少了 $args,或者缓存插件把带参数的请求拦掉了。Nginx 上 try_files $uri $uri/ /index.php?$args; 少了最后那段就会这样。
迁移或换服务器后出现
老服务器是 Apache,新服务器是 Nginx,.htaccess 搬过去了但 Nginx 根本不读它。或者新机器 AllowOverride 设为 None,Apache 也忽略这个文件。这类情况必须先确认新环境的类型。
接了 CDN 之后开始 404
源站正常,通过 CDN 域名访问就 404。常见原因是 CDN 回源路径没带完整 URI,或者开启了「HTML 缓存」但缓存了 404 响应。清理缓存后仍复现,就要看回源配置里的路径改写规则。
中文或特殊字符 slug 404
英文链接正常,中文标题的文章打不开。这类是编码问题:服务器没把 UTF-8 的路径正确解码,或者 Nginx 上开了 merge_slashes 之类影响匹配的选项。把固定链接改成拼音或 ID 是最省事的规避方式。
先确认 404 的来源
一条 curl 就能分清
WordPress 主题渲染的 404 页有站点的页头页脚,看起来「像是自己的网站」;Nginx 或 Apache 返回的 404 是浏览器默认页或服务器默认页。看清这一点,能省掉一半排查时间。
看响应头
curl -I https://你的域名/一个已知存在的内页/。返回 HTTP/1.1 404 时看 Server 字段:写着 nginx 说明是 Nginx 层拦的;写着 Apache 说明是 Web 服务器层;如果 404 页面里出现了主题的样式表链接,则是 WordPress 自己判定的。
绕过 CDN 直连源站
用源站 IP 加 Host 头访问:curl -I -H "Host: 你的域名" http://源站IP/内页/。直连正常、走 CDN 404,问题就在 CDN 的缓存或回源配置上,WordPress 这边不用动。
确认服务器类型与模块
Apache 查重写模块是否加载:apache2ctl -M | grep rewrite,输出里要有 rewrite_module。再看站点配置里的 AllowOverride,必须是 All 或至少包含 FileInfo,否则 .htaccess 形同虚设。
看 WordPress 侧的三个值
wp option get siteurl 与 home 必须一致且协议正确。数据库里如果还是 http:// 而站点已经全站 HTTPS,重写规则会把请求导向 http,再被强制跳转,链路上容易丢参数。核对用 wp option get home。
Apache 环境的标准写法
一段不能多也不能少
WordPress 自己生成的那段规则已经够用,问题通常是它没写进去、被别的规则挤掉,或者文件权限不对。先确认站点根目录下存在 .htaccess,再确认内容完整。
标准规则内容
核心是三行判断:请求的不是真实文件、不是真实目录,就统一交给 index.php。RewriteBase / 在子目录部署时必须改成子目录路径,比如 /blog/,写错会导致所有内页跳到根目录的 404。
- BEGIN / END WordPress 注释之间的内容不要手改
- 缓存与安全插件会在这段之外追加规则
文件权限与属主
.htaccess 权限设为 644、属主与 Web 运行用户一致,否则 WordPress 保存固定链接时写不进去,会提示「无法写入 .htaccess 文件」。用 SFTP 改权限比用面板改更可靠,改完记得重新保存一次固定链接。
子目录部署的坑
站点装在 /wp/ 或 /blog/ 下时,RewriteBase 与站点地址都要带子目录。只改其中一个,会出现「首页正常、内页跳到根目录」的现象。迁移时这一项最容易漏。
强制刷新重写规则
改完规则后执行 wp rewrite flush --hard,它会重建重写规则并尝试写回 .htaccess。没有 WP-CLI 时,去「设置 → 固定链接」点一次「保存更改」效果相同。
如果 .htaccess 里出现了非 WordPress 生成的跳转规则,尤其是带 RewriteRule .* http://别的域名 这种整站重定向,要警惕是否被入侵植入了导流规则,处理思路见WordPress 被黑后的清理与加固。
Nginx 环境要写的三行
.htaccess 在这里不起作用
Nginx 不读 .htaccess,所有重写都要写进站点配置文件。这一点是从 Apache 迁过来的站最常踩的坑——文件都在,规则也在,但没人执行。
location / 里的 try_files
写 try_files $uri $uri/ /index.php?$args;。三个参数依次是:找同名文件、找同名目录、都找不到就交给 index.php 并把原始参数带上。?$args 漏掉的话,分页与搜索结果页会 404,而文章页正常,很容易误判成插件问题。
PHP 段的 fastcgi 配置
location ~ .php$ { fastcgi_pass unix:/run/php/php8.1-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }。SCRIPT_FILENAME 写错会返回空白页或 404,不同面板生成的路径不一样,照抄别家的配置经常在这里出问题。
改完先 test 再 reload
顺序固定:nginx -t 通过后再 systemctl reload nginx。直接 reload 一个语法错误的配置会让整站不可用,而且 reload 失败时旧进程可能已经退出。改配置前先把原文件复制一份带日期后缀。
多站点与子目录
子目录多站点要在对应 location 里单独写规则,且 try_files 的兜底路径要指向子目录的 index.php。规则写错时的表现是主站正常、子站全 404,排查时容易只看主站配置。
环境与规则对照表
照这一列改就不会错位
改之前先确认自己处在哪种环境。判断方法:curl -I 看 Server 头,或问主机商要环境说明。
| 环境 | 规则位置 | 关键写法 | 常见坑 |
|---|---|---|---|
| Apache 独立主机 | 站点根目录 .htaccess | RewriteCond 判断文件与目录后转 index.php | AllowOverride None 时规则不生效 |
| Apache 面板环境 | 面板内的伪静态设置 | 选 wordpress 预设或粘贴标准规则 | 面板另存一份,手改文件会被覆盖 |
| Nginx 独立主机 | 站点 conf 的 location / | try_files $uri $uri/ /index.php?$args; | 漏 $args 导致分页 404 |
| Nginx 反代 Apache | 只在 Nginx 层写 | 兜底转给后端,不在两层重复写 | 两层都写会形成循环重写 |
| 子目录部署 | 子目录规则 | RewriteBase 与站点地址都带子目录 | 只改一处导致内页跳到根目录 |
| 多站点子目录 | 主站规则 + 子站兜底 | 按 SUBDIR_INSTALL 规则生成 | 用单站规则会导致子站全 404 |
| 套 CDN | 源站不动,改回源设置 | 回源保留完整 URI,不缓存 404 | 缓存了错误响应,清理后仍复现 |
换服务器时的完整检查顺序,见WordPress 网站迁移搬家;固定链接结构本身怎么选、改结构对已有收录的影响,见固定链接与伪静态规则。
404 与伪静态常见五问
基本不是。数据库坏了连后台都进不去,或者页面会直接显示数据库错误。后台正常、前台内页 404,几乎可以确定是重写规则没生效。先看站点根目录有没有 .htaccess,再看服务器是不是 Nginx。
会。旧链接会变成 404,已经排名的页面权重会掉。改结构前先导出旧链接清单,改完后用 301 把旧路径逐条指向新路径,并在 Search Console 观察两周。新建站定结构时一次定好,比后期改省事得多,结构选择的细节见固定链接与伪静态规则。
三种可能:文件权限不对导致根本没被读取;AllowOverride 设为 None;服务器是 Nginx 或前面有一层反向代理,请求压根没到 Apache。逐个排除,最直接的办法是临时在文件里写一行必错的语法,看服务器是否报 500——报错说明文件被读了,不报错说明没生效。
先在 CDN 控制台刷新对应 URL,确认源站已恢复正常。长期做法是在 CDN 规则里设置「不缓存 4xx 响应」,只缓存 200。有些 CDN 默认会把 404 缓存几小时,规则修好了但访客仍看到 404,很容易误判成没修好。CDN 侧的配置见CDN 加速配置。
技术上可以,/?p=123 这种形式不依赖重写规则。但代价是 URL 里带问号与数字,对收录和分享都不友好,外贸站尤其不建议。真遇到环境限制改不了规则,更合理的做法是换主机或让服务商调整配置,而不是牺牲 URL 结构。
搬迁或换环境后内页全 404
给我们源站与域名,先分清是谁返回的
提供服务器类型、面板入口与一个出现 404 的示例链接,我们先判断响应来源,再决定改 .htaccess、改 Nginx 配置还是调 CDN 回源。涉及全站 HTTPS 的跳转链路,可一并核对,见SSL 证书与 HTTPS 配置。
电话/微信 13280692153 邮箱 web@wordpressx.com 地址 山东省淄博市张店区电子产业创新园 B 座