quasar cli 在本地開發時 使用 vue router history mode 重新整理會找不到頁面問題

Willy
5 min readMay 6, 2024

--

原先是使用 hash mode ,後來因為某個需求要改成 history mode ,但一直遇到一個問題,就是在任何頁面只要使用重新整理,就會出現 404 Not Found 找不到頁面訊息。

在經過許多交叉測試後,發現在 quasar.config.js 中有設定 proxy ,這意味著所有到 '/'的請求都會被代理到 process.env.API_URL

devServer: {
https: false,
port: 8080,
open: true, // opens browser window automatically
proxy: {
'/': {
target: process.env.API_URL,
changeOrigin: true,
pathRewrite: {'^/': ''},
},
},
},

當你使用 Vue Router 的 history 模式時,如果你直接訪問或刷新一個非根路徑(例如 /user),那麼這個請求會被代理到你的 API 伺服器,而不是被你的開發伺服器處理並返回 index.html 文件。這就是為什麼你會看到 404 錯誤。

要解決這個問題,你需要修改你的代理配置,讓 API 請求和前端路由請求分開。你可以將 API 請求代理到一個特定的路徑,例如 '/api',然後在你的應用程式中相應地修改 API 請求的 URL。這樣,只有到 '/api' 的請求會被代理到你的 API 伺服器,其他的請求(例如前端路由)將被你的開發伺服器處理。

那為什麼 hash mode 不會?

在 hash 模式下,URL 的路徑(path)並不會真正發送到伺服器,只有 hash 之前的部分會被發送。hash 之後的部分(例如 #/user 中的 /user)只會在前端被使用,並不會影響到代理設定。

例如,如果你的應用程式在 hash 模式下,並且發出一個到 #/api/user 的請求,那麼實際上只有 # 之前的部分(也就是 /)會被發送到伺服器。因此,你的代理設定將會將這個請求代理到 process.env.API_URL

所以要將 proxy 調整為如下:

devServer: {
https: false,
port: 8080,
open: true, // opens browser window automatically
proxy: {
'/api': {
target: process.env.API_URL,
changeOrigin: true,
pathRewrite: {'^/api': ''},
},
},
},
  • '/api': 這是一個匹配規則,表示所有以 '/api' 開頭的請求都將被代理。
  • target: process.env.API_URL: 這表示所有匹配的請求將被代理到 process.env.API_URL。(process.env.API_URL 是一個環境變數 .env 檔)
  • changeOrigin: true: 這表示將會改變原始主機的頭部來源到目標URL。
  • pathRewrite: {'^/api': ''}: 這表示在請求被代理到目標伺服器之前,URL 中的 '/api'將被替換為空字串。

改完後要記得也要確認一下, API 請求的 URL,將所有的 API 請求 URL 都加上 '/api' 前綴。例如,如果你之前是這樣發出 API 請求的:

axios.get('/user');

你需要改為:

axios.get('/api/user');

或直接調整源頭 baseURL:

const axiosInstance = axios.create({
baseURL: process.env.NODE_ENV === 'development' ?
'/api' :
process.env.API_URL,
withCredentials: true,
headers: {
'crossDomain': true,
'Content-Type': 'application/json',
},
});

proxy 轉換範例:

假設你的環境變數 process.env.API_URL 的值為 'http://my-api-server.com',並且你的應用程式發出一個到 /api/user 的請求。

由於你的代理設定是將所有以 /api 開頭的請求都代理到 process.env.API_URL,這個請求將被代理到 'http://my-api-server.com'

然後,pathRewrite 的設定 '{'^/api': ''}' 將會將請求 URL 中的 /api 替換為空字串。因此,最終的請求 URL 將會是 'http://my-api-server.com/user'

這就是為什麼你需要在 baseUrl 中加上 /api,並且在 pathRewrite 中將 /api 替換為空字串的原因。這樣可以確保你的請求被正確地代理到你的 API 伺服器。

官方文件

--

--

Willy
Willy

Written by Willy

前端修練筆記本,記錄一些踩雷及學習過程,希望能順便幫助一些,在學習或開發路上卡關的人們。

No responses yet