Vue3+Vite+Nginx部署后刷新404白屏問題的完整排查指南
癥狀:Vue 單頁應(yīng)用(SPA)首次進(jìn)入頁面正常,一刷新就白屏或 404。
一、問題現(xiàn)象
- 訪問
http://your-server/dashboard/home→ 正常 - 在該頁面按 F5 / Ctrl+R 刷新 → 白屏,控制臺(tái)報(bào)大量 404
- 瀏覽器地址欄 URL 沒變,但頁面什么都加載不出來
二、問題本質(zhì):兩個(gè)獨(dú)立原因疊加
刷新白屏這個(gè)現(xiàn)象,背后其實(shí)有兩個(gè)完全不同的原因,必須同時(shí)解決,缺一不可。
原因一:Nginx 不認(rèn)識(shí) Vue Router 的路由路徑(基礎(chǔ)原因)
Vue Router 使用 HTML5 History 模式(createWebHistory)時(shí),/dashboard/home 這類路徑是純前端路由,不對(duì)應(yīng)任何真實(shí)文件。
首次進(jìn)入為什么正常?
用戶從首頁 / 進(jìn)入應(yīng)用,Nginx 找到真實(shí)的 index.html 并返回,Vue 的 JS 運(yùn)行后,Vue Router 接管所有導(dǎo)航。用戶點(diǎn)擊菜單跳轉(zhuǎn)到 /dashboard/home,這是 Vue Router 通過瀏覽器 History.pushState() 完成的,根本沒有向服務(wù)器發(fā)送任何 HTTP 請(qǐng)求,所以正常。
刷新為什么失?。?/strong>
刷新時(shí)瀏覽器向服務(wù)器發(fā)出真實(shí)的 HTTP 請(qǐng)求:GET /dashboard/home。Nginx 在硬盤上找不到對(duì)應(yīng)的文件,于是返回 404。
瀏覽器刷新 → HTTP GET /dashboard/home → Nginx 找文件 → 找不到 → 404
Nginx 修復(fù)方式:配置 try_files,當(dāng)找不到文件時(shí),統(tǒng)一回退到 index.html,讓 Vue Router 接管路由判斷。
location / {
root /home/your-app/dist;
index index.html;
try_files $uri $uri/ /index.html; # 關(guān)鍵:找不到文件就返回 index.html
}
原因二:VITE_PUBLIC_PATH = ./導(dǎo)致資源路徑錯(cuò)位(隱藏原因,也是本文重點(diǎn))
僅修復(fù) Nginx 之后,很多人發(fā)現(xiàn):刷新后頁面不再 404 了,但變成了白屏——HTML 返回了,JS/CSS 卻全部 404。
這是因?yàn)?Vite 打包時(shí),base 配置項(xiàng)(對(duì)應(yīng) VITE_PUBLIC_PATH)決定了 index.html 里所有靜態(tài)資源的引用方式。
./(相對(duì)路徑)vs/(絕對(duì)路徑)的區(qū)別
當(dāng) VITE_PUBLIC_PATH = ./ 時(shí),打包產(chǎn)物 index.html 內(nèi)容如下:
<script type="module" crossorigin src="./assets/index-BsHqOBiK.js"></script> <link rel="stylesheet" href="./assets/index-Df9KKQPD.css" rel="external nofollow" >
./ 是相對(duì)于當(dāng)前頁面 URL 的路徑,瀏覽器會(huì)根據(jù)當(dāng)前 URL 來解析:
| 當(dāng)前 URL | ./assets/index.js 解析結(jié)果 | 服務(wù)器實(shí)際文件 | 結(jié)果 |
|---|---|---|---|
/(首頁) | /assets/index.js | /dist/assets/index.js | ? 正常 |
/dashboard/home(刷新) | /dashboard/assets/index.js | 不存在 | ? 404 |
當(dāng) VITE_PUBLIC_PATH = / 時(shí),打包產(chǎn)物 index.html 內(nèi)容如下:
<script type="module" crossorigin src="/assets/index-BsHqOBiK.js"></script> <link rel="stylesheet" href="/assets/index-Df9KKQPD.css" rel="external nofollow" >
/ 開頭是絕對(duì)路徑,瀏覽器無論在哪個(gè) URL 下,都固定從網(wǎng)站根路徑加載:
| 當(dāng)前 URL | /assets/index.js 解析結(jié)果 | 服務(wù)器實(shí)際文件 | 結(jié)果 |
|---|---|---|---|
/(首頁) | /assets/index.js | /dist/assets/index.js | ? 正常 |
/dashboard/home(刷新) | /assets/index.js | /dist/assets/index.js | ? 正常 |
為什么首次進(jìn)入正常,刷新才白屏?
因?yàn)?quot;首次進(jìn)入"通常是從網(wǎng)站根路徑 / 加載的 index.html,此時(shí) ./ 被正確解析為 /assets/...,資源加載成功,Vue 啟動(dòng)。
后續(xù)的頁面跳轉(zhuǎn)(/dashboard/home)是 Vue Router 純前端路由,不觸發(fā)新的 HTML 請(qǐng)求,資源早就加載完畢了,所以一切正常。
刷新時(shí),瀏覽器重新請(qǐng)求 /dashboard/home 對(duì)應(yīng)的 HTML,Nginx 回退返回 index.html,但瀏覽器此時(shí) URL 是 /dashboard/home,./assets/... 被解析為 /dashboard/assets/...,全部 404,白屏。
三、完整修復(fù)步驟
第一步:修改 Vite 打包配置
找到項(xiàng)目里的 .env.production(或 vite.config.ts 里的 base 字段):
# .env.production - VITE_PUBLIC_PATH = ./ + VITE_PUBLIC_PATH = /
或直接在 vite.config.ts 里:
export default defineConfig({
- base: './',
+ base: '/',
})
第二步:檢查 Nginx 配置
確保 Nginx 有正確的 try_files 兜底:
server {
listen 80;
server_name your-domain.com;
root /home/your-app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html; # 必須有這行
}
# 靜態(tài)資源緩存(可選)
location ~* \.(js|css|png|jpg|gif|ico|svg|woff2?)$ {
expires 30d;
access_log off;
}
}
注意 try_files 最后參數(shù)必須是 URI(如 /index.html),不能是文件系統(tǒng)絕對(duì)路徑(如 /home/app/dist/index.html),否則 Nginx 會(huì)把它當(dāng) URL 再次查找,導(dǎo)致死循環(huán)或 404。
第三步:重新構(gòu)建并部署
npm run build # 將 dist/ 目錄上傳到服務(wù)器 nginx -s reload
第四步:驗(yàn)證構(gòu)建產(chǎn)物
grep -o 'src="[^"]*"' dist/index.html | head -5
正確輸出(絕對(duì)路徑,/ 開頭):
src="/assets/index-BsHqOBiK.js"
錯(cuò)誤輸出(相對(duì)路徑,./ 開頭):
src="./assets/index-BsHqOBiK.js"
四、常見錯(cuò)誤配置(避坑)
錯(cuò)誤一:try_files 用文件路徑而非 URI
# ? 錯(cuò)誤:/home/app/dist/index.html 被當(dāng)作 URL 解析 try_files $uri $uri/ /home/app/dist/index.html; # ? 正確:/index.html 是 URL 路徑,Nginx 會(huì)用 root 拼接找到真實(shí)文件 try_files $uri $uri/ /index.html;
錯(cuò)誤二:alias + try_files 兜底路徑寫錯(cuò)
location /app {
alias /home/app/dist/;
# ? 錯(cuò)誤:兜底 URI 用 /index.html,
# 這會(huì)跳回 location /,然后用 root 目錄找文件,與 alias 目錄不同
try_files $uri $uri/ /index.html;
# ? 正確:兜底 URI 帶上 location 前綴,讓請(qǐng)求再次進(jìn)入這個(gè) location
try_files $uri $uri/ /app/index.html;
}
錯(cuò)誤三:Hash 模式不需要任何 Nginx 配置
如果你使用的是 createWebHashHistory(URL 帶 #,如 /#/dashboard/home),# 后面的內(nèi)容不會(huì)發(fā)送給服務(wù)器,Nginx 永遠(yuǎn)只收到 GET /,不存在刷新 404 問題,無需任何特殊配置。
只有 createWebHistory(無 # 的干凈 URL)才需要上述配置。
五、總結(jié)
| 問題 | 原因 | 修復(fù)方式 |
|---|---|---|
| 刷新 404 | Nginx 不認(rèn)識(shí)前端路由路徑 | 配置 try_files $uri $uri/ /index.html |
| 刷新白屏(資源 404) | VITE_PUBLIC_PATH = ./ 相對(duì)路徑在非根 URL 下解析錯(cuò)誤 | 改為 VITE_PUBLIC_PATH = / 使用絕對(duì)路徑 |
兩個(gè)問題獨(dú)立存在,必須同時(shí)解決。實(shí)際排查時(shí),往往先修了 Nginx 發(fā)現(xiàn)還是白屏,再去查資源請(qǐng)求路徑,才發(fā)現(xiàn)是打包配置的問題。
以上就是Vue3+Vite+Nginx部署后刷新404白屏問題的完整排查指南的詳細(xì)內(nèi)容,更多關(guān)于Vue3 Vite Nginx部署后刷新404白屏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue中使用create-keyframe-animation與動(dòng)畫鉤子完成復(fù)雜動(dòng)畫
這篇文章主要介紹了Vue中使用create-keyframe-animation與動(dòng)畫鉤子完成復(fù)雜動(dòng)畫,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04
vue3+vant4封裝日期時(shí)間組件方式(年月日時(shí)分秒)
這篇文章主要介紹了vue3+vant4封裝日期時(shí)間組件方式(年月日時(shí)分秒),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vue+vant實(shí)現(xiàn)商品列表批量倒計(jì)時(shí)功能
這篇文章主要介紹了vue+vant實(shí)現(xiàn)商品列表批量倒計(jì)時(shí)功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
在Vue3項(xiàng)目中使用VueCropper裁剪組件實(shí)現(xiàn)裁剪及預(yù)覽效果
這篇文章主要介紹了在Vue3項(xiàng)目中使用VueCropper裁剪組件(裁剪及預(yù)覽效果),本文分步驟結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07
axios中post請(qǐng)求json和application/x-www-form-urlencoded詳解
Axios是專注于網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求的庫,相比于原生的XMLHttpRequest對(duì)象,axios簡(jiǎn)單易用,下面這篇文章主要給大家介紹了關(guān)于axios中post請(qǐng)求json和application/x-www-form-urlencoded的相關(guān)資料,需要的朋友可以參考下2022-10-10
基于VUE實(shí)現(xiàn)判斷設(shè)備是PC還是移動(dòng)端
這篇文章主要介紹了基于VUE實(shí)現(xiàn)判斷設(shè)備是PC還是移動(dòng)端,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07

