部署網站或應用程式後出現 404 錯誤,如何修復
如果你的應用程式在本機運行正常,但部署後頁面卻回傳 404,最常見的原因是缺少單頁應用程式(SPA)的路由設定:伺服器尋找一個名為 /dashboard 的檔案,但該檔案並不存在,因為這個路由只存在於 JavaScript 之中。修復方法是設定回退規則,為應用程式的路由提供 index.html。其他成因包括建構輸出中缺少檔案、路徑大小寫敏感、結尾斜線的差異、錯誤的基礎路徑,以及從未部署的 API 路由。
先記下確切是哪一個網址出現 404,以及你是如何到達那裡的。出現的模式會直接指向成因。
第一步:找出模式
| 你看到的情況 | 最可能的成因 | 前往 |
|---|---|---|
| 首頁正常,點擊連結正常,但重新整理或直接開啟深層連結時出現 404 | 沒有 SPA 回退 | 第二步 |
| 所有頁面都出現 404,包括首頁 | 發佈了錯誤的資料夾,或建構沒有成功部署 | 第三步 |
| 頁面能載入,但圖片、字型或腳本出現 404 | 建構中缺少檔案,或路徑錯誤 | 第四步 |
/about/ 正常,但 /about 出現 404(或相反) | 結尾斜線的處理方式 | 第五步 |
/About 出現 404,但 /about 正常 | 伺服器區分大小寫 | 第四步 |
頁面能載入,但對 /api/... 的資料請求出現 404 | API 未部署或未設定路由 | 第六步 |
| 來自舊網站的舊網址出現 404 | 缺少重新導向 | 第七步 |
| 只在自訂網域上出現 | DNS 或網域設定 | 第八步 |
要查看真正的狀態碼,請開啟開發人員工具(按右鍵 → 檢查),前往 Network 分頁,重新載入,然後查看第一個請求的狀態。
第二步:加入 SPA 回退
這是最經典的情況。在 React、Vue 或 Svelte 的單頁應用程式中,伺服器只有少數真實的檔案:index.html,以及一些 JavaScript 和 CSS。像 /dashboard 或 /projects/42 這樣的路由,是由瀏覽器中的路由器處理的。
- 點擊連結可以運作:路由器會改變網址,並在不向伺服器要求的情況下繪製新頁面。
- 重新整理或直接開啟連結會失敗:瀏覽器向伺服器要求
/dashboard,伺服器沒有這個檔案,於是回傳 404。
修復方法是設定一條規則:如果請求不符合任何真實檔案,就以 200 狀態回傳 index.html,讓路由器接手。具體做法視乎主機而定(請查閱你所用主機目前的文件,因為細節會更改):
| 主機 | 常見的回退規則 |
|---|---|
| Netlify | 在已發佈的資料夾中放一個 _redirects 檔案,內容為 /* /index.html 200 |
| Vercel | 在 vercel.json 中加入重寫規則,把所有路徑導向 /index.html(框架預設通常已處理) |
| Cloudflare Pages | 如果沒有頂層的 404.html,預設會提供類似 SPA 的回退 |
| Nginx | 在 location / 區塊中加入 try_files $uri $uri/ /index.html; |
| Apache | 在 .htaccess 中加入重寫規則,把非檔案請求導向 index.html |
| GitHub Pages | 沒有伺服器端重寫;常見的變通方法是使用哈希路由,或使用會重新導向的 404.html |
確保這條規則不會攔截真實的檔案:對 /assets/app.js 的請求,仍必須回傳 JavaScript 檔案。如果它回傳的是 index.html,你就會看到空白頁面,以及「Failed to load module script」錯誤。請參閱如何修復空白頁面。
此外,還要為路由器加入通配路由,讓不符合任何頁面的網址顯示友善的「找不到頁面」,而不是什麼都不顯示。
如果你無法更改伺服器設定,哈希路由(網址如 /#/dashboard)可以避開這個問題,因為 # 之後的部分永遠不會傳送到伺服器。這只是一個變通方法,並非首選:網址較難看,對搜尋引擎也不太友善。
在伺服器端渲染或於建構時生成頁面的框架(Next.js、Astro 及類似工具),通常為每個頁面提供真實的檔案或伺服器路由,因此這類問題在這些框架中較少出現。它們的對應情況是:某個頁面在建構時從未被生成。
第三步:檢查實際部署的內容
如果所有東西都出現 404,伺服器很可能沒有提供你建構好的應用程式。
- 正確的資料夾。 主機必須發佈建構輸出(Vite 通常是
dist,Create React App 通常是build,靜態 Next.js 匯出通常是out),而不是專案根目錄。 - 建構確實有執行。 閱讀部署記錄。如果建構失敗,主機可能根本沒有部署任何東西,或仍然是舊版本。
index.html位於已發佈資料夾的頂層,而不是在子資料夾中。- 基礎路徑相符。 如果應用程式是透過
example.com/app/提供的,就必須以該基礎路徑建構(Vite 的base、React Router 的basename),否則每個路由和資產都會找不到。
第四步:修復缺少的檔案和錯誤路徑
當頁面能載入,但資產出現 404 時:
- 大小寫敏感。 macOS 和 Windows 通常把
Logo.png和logo.png視為同一個檔案。大部分 Linux 伺服器則不會。確保每個引用都與實際檔案名稱完全一致。 - 建構以外的檔案。 在 Vite 中,
public/內的檔案會原樣複製,並從根目錄引用(/logo.png)。在代碼中導入的檔案則會被打包。放在專案其他位置的檔案,可能根本沒有被部署。 - 相對路徑。
images/photo.jpg是以目前的網址為基礎解析的,所以在/blog/post-1之下會失效。請改用/images/photo.jpg。 - 上傳的檔案儲存在本機磁碟。 如果用戶的上傳內容寫入了伺服器自己的資料夾,那麼每次部署新版本時,它們都會消失。請改用正式的檔案儲存服務。
第五步:一致地處理結尾斜線
/about 和 /about/ 是不同的網址。各主機對於是否加上或去掉斜線的處理有所不同,而如果它與你的連結或路由器不一致,就可能產生 404 或重新導向迴圈。請選定一種風格,讓連結都使用這種風格,並設定主機把另一種形式重新導向至它。保持一致也有助於搜尋引擎,否則它們可能會把每個頁面都視為兩個副本。
第六步:修復出現 404 的 API 路由
如果頁面能載入,但網絡分頁顯示 /api/... 的請求回傳 404:
- 後端未部署。 靜態主機只提供檔案;後端必須在某處運行。
- 正式環境的路由方式不同。 在開發時,代理可能把
/api轉發到另一個伺服器。在正式環境中,主機需要有等效的重寫,或前端必須直接呼叫 API 的真實位址。 - SPA 回退攔截了它。 如果 API 請求回傳了以 200 狀態的
index.html,代表回退規則範圍太廣。請把/api/*排除在外。
已發佈應用程式對 /api/orders 的請求回傳 404,但它們在預覽中可以運作。請檢查預覽與已發佈應用程式中 /api 的路由方式有何不同,並讓已發佈的前端以相同方式連接後端。
第七步:重新導向舊網址
如果你從其他網站遷移過來,或重新組織了網站結構,人們和搜尋引擎仍在使用的舊網址就會出現 404。請為每個舊網址加入 301(永久)重新導向,指向其新位置。保存一份清單,並在上線後抽樣測試。我們的遷移 WordPress 網站指南說明了如何建立這份清單。
第八步:檢查網域
如果應用程式在主機的位址上運作正常,但在你的自訂網域上出現 404,那可能是網域指向了錯誤的專案,或者主機尚未把該網域附加到你的網站上。請檢查 DNS 記錄和主機的網域設定。請參閱如何連接自訂網域。
讓真正的 404 頁面有用
有些 404 是正確的:有人輸入了錯誤的網址。請讓該頁面有幫助:
- 一段簡短的訊息,加上通往首頁和主要區段的連結
- 如果網站有搜尋功能,加上搜尋框
- 與網站其他部分相同的標題列和導覽
在你的設定允許的情況下,對於不存在的頁面應回傳真正的 404 狀態。以 200 狀態回傳的「找不到」訊息,就是搜尋引擎所說的軟 404,它會浪費搜尋引擎的爬取時間,並令索引出現混亂。
常見錯誤
- 只靠點擊來測試。 一定要把深層網址貼到新分頁並重新整理來測試。
- 回退規則攔截了所有東西。 資產和 API 路由都回傳
index.html,導致空白頁面和令人困惑的 API 錯誤。 - 大小寫不一致,只在伺服器上出錯。
- 部署了原始碼資料夾,而不是建構輸出。
- 重組網址卻沒有重新導向。 每個舊連結都會變成 404。
Mythex 中的 404
在 Mythex,你從工作區發佈,靜態前端會以靜態網站形式部署。如果已發佈的頁面出現 404,請把確切的網址、它是在重新整理還是點擊時出現,以及網絡分頁顯示的內容告訴代理,並要求它檢查路由。修復之後請重新發佈,因為正式的應用程式是一個快照,直至你重新發佈為止。如果你最近更改了專案,而正式網站看起來仍是舊的,請重新發佈並強制重新整理。如果建構失敗,請使用發佈對話框中的 用 AI 修復。請參閱文件中的如何發佈和發佈疑難排解,以及我們的除錯 AI 建構應用程式指南。
404 檢查清單
- 已記下確切出現 404 的網址,以及是在點擊、重新整理,還是兩者皆有
- SPA 回退以 200 狀態為應用程式路由提供
index.html - 回退已排除真實檔案和
/api/* - 路由器有通配的「找不到頁面」路由
- 已發佈的是建構輸出資料夾,且建構已成功
- 基礎路徑與應用程式的提供位置相符
- 檔案名稱大小寫與每個引用一致
- 資產路徑以
/開頭 - 結尾斜線風格一致
- API 路由已在正式環境中部署並設定路由
- 舊網址已設定 301 重新導向
- 已把深層連結貼到新分頁中測試
常見問題
為什麼我的 React 應用程式在重新整理頁面時出現 404?
在單頁應用程式中,像 /dashboard 這樣的路由只存在於 JavaScript 之中。點擊連結可以運作,因為路由器在瀏覽器內處理;但重新整理時,瀏覽器會向伺服器要求一個並不存在的 /dashboard 檔案。修復方法是設定回退規則,為應用程式的路由提供 index.html。
如何在 Netlify、Vercel 或 Nginx 上加入 SPA 回退?
在 Netlify,於 _redirects 檔案中加入 /* /index.html 200。在 Vercel,在 vercel.json 中加入重寫規則,把所有路徑導向 /index.html。在 Nginx,於 location 區塊中使用 try_files $uri $uri/ /index.html;。規則會更改,請查閱你所用主機的文件。
為什麼部署後我的圖片或檔案出現 404?
通常是因為檔案不在建構輸出之中、路徑的大小寫與實際檔案不符(伺服器通常區分大小寫,而你的筆記型電腦則不一定),或者路徑應以斜線開頭卻使用了相對路徑。
不存在的頁面應該回傳真正的 404 狀態嗎?
應該。提供一個有用的找不到頁面,並在你的設定允許的情況下使用 404 狀態。搜尋引擎會把以 200 狀態回傳的「找不到」訊息視為軟 404,這會浪費爬取資源,並可能令索引出現混亂。