前段時間上線了使用vue全家桶搭建的個人博客,訪問地址爲Civitasv’s blog。採用了前後端完全分離模式,將前端頁面部署到GitHub pages頁面,後端部分部署至阿里雲個人服務器,僅用於提供數據和rest服務接口。之前的是採用hash模式,並無問題,但最近感覺很多#
不太美觀,且不利於SEO
,因此考慮將其改變爲history
模式,遇到了一些問題,特此記錄分享。
0 簡述vue路由history模式原理
首先,要理解爲了構建SPA應用,需要引入vue前端路由系統,其目的在於改變視圖不向服務器發送請求,也就是說,向服務器發送頁面請求事實上只有最開始的一次,其餘的頁面均依賴前端路由動態改變引入的資源文件實現。
在實現上述功能時,vue路由history模式利用了H5新增的pushState()
和replaceState()
接口方法,它們分別可以添加和修改歷史記錄條目。這些方法通常與window.onpopstate
配合使用。假設在http://starss.me
上中執行history.pushState(null, null, "home")
,瀏覽器地址會變爲http://starss.me/home/
,但頁面不會刷新,也即不會向服務器發送請求,接着vue router就對該url進行處理,實現無刷新頁面變化。
1 404問題
vue官方文檔和很多博客均提到history
模式下應該提供後臺支持.
當你使用 history 模式時,URL 就像正常的 url,例如
http://yoursite.com/user/id
,也好看!不過這種模式要玩好,還需要後臺配置支持。因爲我們的應用是個單頁客戶端應用,如果後臺沒有正確的配置,當用戶在瀏覽器直接訪問
http://oursite.com/user/id
就會返回 404,這就不好看了。
首先解釋下爲什麼會出現404,如果在http://starss.me/
下存在你的主頁即index.html
,假如在hash模式下手動輸入/刷新了這樣一個url鏈接:
http://starss.me/#/home
則在請求服務器時,會自動去掉#之後的內容,因此服務器會去http://starss.me
下尋找index.html
,成功後返回頁面,改變路由後,通過vue路由配置找到對應的資源即可。但如果我們將其改變爲history模式之後,再次手動輸入/刷新下面鏈接:
http://starss.me/home
這樣服務器顯然會去http://starss.me/home
下尋找主頁資源,自然不可能找到,因此一定會出現404錯誤了。
這也即是官網中說到:“要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html
頁面”的原因了。這個目的就是在無法匹配資源時,手動配置返回一個應當返回的資源,這個資源也就是我們的主頁了,接着vue router就會解析出路由地址,然後根據自己的配置信息找到對應的資源了。
同樣的原因,在使用GitHub page時,如果index.html
只存在於根目錄中,手動輸入/刷新訪問上面的url也會報404錯誤,結合其原理,我想到的解決的思路有兩個:
- GitHub page在404時會訪問404.html頁面,因此只需要將index.html備份一份,命名爲404.html即可,放置在根目錄即可,這樣控制檯仍然會報404錯誤,但可以正常顯示;
- 對於url :
http://starss.me/home
,我們還可以新建一個home文件夾,將index.html複製一份至該文件夾,這樣刷新也當然可以訪問到它,而且控制檯也並不會報404錯誤。
我的建議是:
-
如果路由很少,可以按照第二種方式,對每一個路由均新建一個文件夾,然後複製一份index.html,此時也不需要單獨配置404頁面,GitHub page會給提供(當然也可以配置);
-
如果路由很多,最好還是按照第一種方式,而且注意這種方式下404.html會被佔用,需要單獨配置404頁面,方法是在路由匹配最下部添加一條即可:
{ path: '*', // 此處需特別注意至於最底部 name: '404', component: () => import('../views/common/404'), meta: { title: '404 | Civitasv\'s blog' }, }
按照我的理解,第一種方式其實和前後端不分離模式解決方法思想一致,只是提供一個無法匹配任何已有資源時的候選資源罷了。而第二種可以看作是純前端的解決方式,可以根據項目實際情況選擇使用。
2 二級路由刷新空白問題
這個是路徑的原因,只需要在vue.config.js文件中配置publicPath: "/",
即可,事實上,這只是個絕對路徑和相對路徑的問題罷了。
結語
GitHub page鏈接:https://github.com/Civitasv/civitasv.github.io
博客源碼鏈接:https://github.com/Civitasv/blog
如果仍不清楚,可以留言給我,我看到就會回覆
如果喜歡這篇文章,希望你點個贊
and如果有興趣的話,關注公衆號:林木菌,和我一起成長pa~~