解決SPA部署到GitHub pages重新整理產生404的問題
最近在開發分頁式網頁時,初次把SPA專案部署到GitHub上使用。但是發現當使用者在分頁reload時,會產生404的問題。
以下就來介紹為什麼會有這種狀況發生。
404的狀況
例如使用者的情境為:
- 進入test.io/
- 打開test.io/form
- 重新整理test.io/form
- response 404 http status
你可能會覺得很疑惑,其他網站就可以為什麼這個就不行?
原因其實也很容易理解,GitHub pages只支援靜態網頁的,網址對應到的也是真實路徑。
以上面的例子來說,造訪test.io/就相當於是造訪 / 的路徑,也就是對應 /index.html。
當你造訪test.io/form時,對GitHib pages而言,/form/index.html 是不存在的,當然會拋出404 status。
SPA的路徑
所以這跟SPA有什麼關係?請注意,SPA顧名思義就是單頁式網頁,就表示他是“不換頁”的網頁,只是看起來像換頁而已。
也就是瀏覽分頁都是在同一個頁面上,所以只要重新整理,又會回到原本的分頁了。
我們通常會搭配,例如: router-dom之類的套件來達到分頁效果。
但是SPA重新整理就會遇到上面的404的狀況,那該如何在GitHub pages解決呢?
重新導向
GitHub pages有提供導向到404的custom page,所以我們可以善用這點來做一些變化。
如果我們在導向到自己製作的404頁面,並且導向到我要的頁面,這不就解決問題了嗎?
也就是說,我們可以把情境變成:
- 進入test.io/
- 打開test.io/form
- 重新整理test.io/form
- 404 導向到自己的404頁面
- 在404頁面分析網址,導向到 /form
流程清楚之後,再來就來談如何實作
404頁面建置
網路上有大大分享了如何重新導向的程式碼,懶得看一大串英文的這邊幫你翻譯一下。
請將以下程式碼放到404.html裡面(通常放在public)
當找不到頁面時,就會重新導向,並且將後面的參數變成query和hash夾在後面。
例如:
- test.io/form會變成test.io/?p=form
更改location到test.io/?p=form的時候,就會回到首頁。
因此,把下面這段script加到你的404.html內
1 | var segmentCount = 0; |
補充:
segmentCount為階層,如果你寫成1的話:
- test.io/form/123 會變成 test.io/form/?p=123
設定好之後,你重新整理頁面會發現404的頁面已經不再出現了。
再來就是設定導向到特定分頁的程式碼。
導入分頁
接下來我們要做的事情是,將後面的query分析成指定的路徑。
這邊會用到的是window.history.replaceState,使用他可以改變網頁路徑。
所以以下是分析網址的演算法,放到你的首頁即可(通常在public)
把下面這段script加到你的index.html內
1 | <script type="text/javascript"> |
再來你重新整理頁面的時候,就會發現的網址列有閃一下,那就是重新導入的動作,表示已經成功了。
前端的寫法
這邊以React為例,用react-router-dom的正常寫法即可。
1 | ... |
其他做法
事實上有其他的方法,以React為例:
可以使用HashRouter,剛剛在上面有提到,如果在網址內包含query和hash是可以的,因此就是利用這個原理。