跳至內容
伺服器與 .htaccess

WordPress 文章回傳 404,但首頁正常

如果首頁載入正常,但每一篇個別文章與頁面都回傳 404,那就是 WordPress 依賴的網址重寫規則在你的 .htaccess 檔案中遺失或損毀了

發布於

如果首頁載入正常,但每一篇個別文章與頁面都回傳 404,那就是 WordPress 依賴的網址重寫規則在你的 .htaccess 檔案中遺失或損毀了。最快的修正方式:進入 wp-admin 的 設定 → 永久連結,什麼都不改,直接按 儲存變更。這會強制 WordPress 重新產生重寫區塊。如果 404 仍然存在,那就是你的 .htaccess 無法被網頁伺服器寫入、Apache 被設定成忽略它,或是你用的是 Nginx(它根本不使用 .htaccess)。

為什麼首頁正常,文章卻不行

首頁正常,是因為對 / 的請求是直接由網站根目錄的 index.php 提供的,不需要任何重寫。

/2026/my-post/ 的請求則不同。這個路徑在磁碟上並不是一個真實的資料夾。為了讓 WordPress 回應它,Apache 必須在內部把請求路由到 index.php,接著 WordPress 讀取 REQUEST_URI,將它與資料庫中 rewrite_rules 選項所儲存的重寫規則做比對,解析查詢變數(WP::parse_request()),然後載入正確的文章。

從 Apache 交棒給 index.php 的這個環節,正是會出問題的地方。它完全依賴 .htaccess 中的這個區塊:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

那兩行 RewriteCond 的意思是:如果請求的路徑不是真實的檔案(!-f)也不是真實的目錄(!-d),就把它交給 index.php。移除這個區塊後,Apache 會去找一個實際名為 /2026/my-post/ 的目錄,找不到,於是回傳它自己的 404——在 WordPress 看到這個請求之前就發生了。

為什麼儲存永久連結時 WordPress 會覆寫 .htaccess

這一段是大多數教學會略過的部分。當你在永久連結畫面按下儲存時,WordPress 會呼叫 flush_rewrite_rules()。在 .htaccess 可寫入的 Apache 環境下,這會觸發 save_mod_rewrite_rules(),它透過 WP_Rewrite::mod_rewrite_rules() 重新產生上面那個區塊,並用 insert_with_markers() 寫回檔案。

insert_with_markers() 只會動到 # BEGIN WordPress# END WordPress 之間的內容。這兩個標記以外的所有內容都不會被更動;標記以內的所有內容則會被捨棄並重寫。較新版本的 WordPress 甚至會直接把警告印在檔案裡:

這些標記之間指令的任何變更都會被覆寫。

所以「WordPress 覆寫了我的 .htaccess」是真的,但範圍很小:它只會重寫自己標記的那個區塊,而且只在檔案可寫入時才會這麼做。如果檔案 不可 寫入,儲存動作對磁碟不會有任何實際效果。WordPress 會在永久連結畫面顯示一則黃色提示,要你手動貼上規則;如果你沒注意到那則提示,你的重寫區塊就會一直缺失,每篇文章也會持續回傳 404。

如何修正,按順序來

1. 重新儲存你的永久連結。 設定 → 永久連結 → 儲存變更。不需要任何修改。這會重新執行 flush 並重寫區塊。大多數情況都能靠這一步解決,包括網站搬移後殘留的過期規則。

2. 確認 .htaccess 存在且可寫入。 它和 wp-config.php 位在同一個資料夾。它是一個 dotfile,所以要在你的 FTP 用戶端啟用「顯示隱藏檔案」,或使用:

ls -la /path/to/wordpress/.htaccess

如果它不存在,就建立一個並貼入正確的區塊。如果你的安裝位在某個子目錄,RewriteBase 和最後那條重寫的目標路徑就必須與該路徑相符——弄錯這點,是手動貼上的區塊仍然出現 404 最常見的原因。我們的 .htaccess 產生器 會依照你的安裝路徑產生完全正確的區塊,讓你不必用猜的。

3. 確認 Apache 被允許讀取 .htaccess 如果虛擬主機設定了 AllowOverride None,Apache 就會完全忽略這個檔案,不論其內容為何。你需要在 WordPress 目錄上設定 AllowOverride All(至少要 FileInfo)。這是在伺服器設定裡,不是在 .htaccess 裡,所以需要伺服器的存取權限:

<Directory /var/www/html>
    AllowOverride All
</Directory>

4. 確認 mod_rewrite 已啟用。 在 Debian/Ubuntu 上:

sudo a2enmod rewrite
sudo systemctl restart apache2

5. 在 Nginx 上,沒有 .htaccess 重寫規則改寫在 server 區塊裡:

location / {
    try_files $uri $uri/ /index.php?$args;
}

快速診斷:這是誰的 404?

看看那個 404 頁面。如果它是一個沒有樣式的 Apache 或主機錯誤頁,代表 Apache 根本沒到達 WordPress——這是 .htaccess 或伺服器設定的問題(步驟 2–4)。如果它是 你佈景主題 那個有樣式的 404,代表 WordPress 有收到請求但無法比對——資料庫中的規則過期了,而重新儲存永久連結(步驟 1)就是修正方法。光是這一項區分,就能幫大多數人省下一小時的瞎猜。

不要做的事

不要一開始就停用你所有的外掛。 純粹的「文章 404、首頁正常」症狀是重寫問題,不是外掛衝突。停用外掛是論壇上的反射式答案,但幾乎從來碰不到這個問題。

不要對你的 .htaccess 執行 chmod 777 WordPress 需要的是讓 網頁伺服器使用者 能寫入這個檔案,這和讓全世界都能寫入不是同一回事。搭配正確擁有者的 644 就沒問題且安全;777 是一個安全漏洞,而且反正也修不好路由問題。

不要把自訂的重寫規則貼在 # BEGIN WordPress / # END WordPress 標記之內。 下次只要有人儲存永久連結,它們就會被清掉。請把自訂指令放在 # BEGIN WordPress 這一行 之上

不要重新安裝 WordPress。 核心檔案沒有問題。這只是一段文字區塊遺失,不是安裝損毀。

不要怪你的佈景主題。 永久連結路由是 WordPress 核心的功能。佈景主題無法造成這個問題,也無法修正它。

還是卡住了?

如果你已經重新儲存了永久連結、確認區塊存在且可寫入、也設定了 AllowOverride All,那剩下的嫌疑犯就是某個安全性外掛,或某條主機層級的規則在你不知情的情況下重新產生或鎖住了 .htaccess。在儲存永久連結後立刻檢查檔案的修改時間戳記——如果它沒有變,就代表有東西在阻擋寫入。用 .htaccess 產生器 重新產生一個乾淨的區塊,貼進去,然後用強制重新整理再測試一次。