一、爲何要有 hash 和 historyhtml
對於 Vue 這類漸進式前端開發框架,爲了構建 SPA(單頁面應用),須要引入前端路由系統,這也就是 Vue-Router 存在的意義。前端路由的核心,就在於 —— 改變視圖的同時不會向後端發出請求。前端
爲了達到這一目的,瀏覽器當前提供瞭如下兩種支持:vue
#
符號(此 hash 不是密碼學裏的散列運算)。http://www.abc.com/#/hello
,hash 的值爲 #/hello
。它的特色在於:hash 雖然出如今 URL 中,「#」後面的內容不會被包括在 HTTP 請求中,對後端徹底沒有影響,所以改變 hash 不會從新加載頁面。pushState()
和 replaceState()
方法。(須要特定瀏覽器支持)back
、forward
、go
的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會當即向後端發送請求。所以能夠說,hash 模式和 history 模式都屬於瀏覽器自身的特性,Vue-Router 只是利用了這兩個特性(經過調用瀏覽器提供的接口)來實現前端路由。segmentfault
二、使用場景後端
通常場景下,hash 和 history 均可以,除非你更在乎顏值,#
符號夾雜在 URL 裏看起來確實有些不太美麗。瀏覽器
若是不想要很醜的 hash,咱們能夠用路由的 history 模式,這種模式充分利用 history.pushState API 來完成
URL 跳轉而無須從新加載頁面。—— Vue-router 官網。tomcat
另外,根據 Mozilla Develop Network 的介紹,調用 history.pushState()
相比於直接修改 hash
,存在如下優點:app
pushState()
設置的新 URL 能夠是與當前 URL 同源的任意 URL;而 hash
只可修改 #
後面的部分,所以只能設置與當前 URL 同文檔的 URL;pushState()
設置的新 URL 能夠與當前 URL 如出一轍,這樣也會把記錄添加到棧中;而 hash
設置的新值必須與原來不同纔會觸發動做將記錄添加到棧中;pushState()
經過 stateObject
參數能夠添加任意類型的數據到記錄中;而 hash
只可添加短字符串;pushState()
可額外設置 title
屬性供後續使用。固然啦,history
也不是樣樣都好。SPA 雖然在瀏覽器裏遊刃有餘,但真要經過 URL 向後端發起 HTTP 請求時,二者的差別就來了。尤爲在用戶手動輸入 URL 後回車,或者刷新(重啓)瀏覽器的時候。框架
hash
模式下,僅 hash
符號以前的內容會被包含在請求中,如 http://www.abc.com
,所以對於後端來講,即便沒有作到對路由的全覆蓋,也不會返回 404 錯誤。history
模式下,前端的 URL 必須和實際向後端發起請求的 URL 一致,如 http://www.abc.com/book/id
。若是後端缺乏對 /book/id
的路由處理,將返回 404 錯誤。Vue-Router 官網裏如此描述:「不過這種模式要玩好,還須要後臺配置支持……因此呢,你要在服務端增長一個覆蓋全部狀況的候選資源:若是 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。」結合自身例子,對於通常的 Vue + Vue-Router + Webpack + XXX 形式的 Web 開發場景,用 history
模式便可,只需在後端(Apache 或 Nginx)進行簡單的路由配置,同時搭配前端路由的 404 頁面支持code
以上三點摘自https://segmentfault.com/q/1010000010340823
四、history模式下如何作後端配置
history模式下直接打開導出的網頁時,頁面是沒法渲染成功的
文件加載正常,但頁面卻沒顯示任何內容。
這是由於在history模式下,瀏覽器去打開「.../padExam/home」頁面時,會向服務端發送http請求來獲取頁面資源,而此處爲本地路徑,後端沒有對路徑進行配置,請求天然以失敗了結,所以須要在服務端後臺配置文件的訪問根目錄
上圖所示,在設置了訪問的根目錄後,將項目部署到tomcat,項目成功啓動
以上只是一個簡單的例子,在真實的開發環境中後端須要作複雜的路徑配置。