對於 Vue 這類漸進式前端開發框架,爲了構建 SPA(單頁面應用),須要引入前端路由系統,這也就是 Vue-Router 存在的意義。前端路由的核心,就在於 —— 改變視圖的同時不會向後端發出請求。html
爲了達到這一目的,瀏覽器當前提供了一下兩種方法:前端
例以下面這個URL:後端
http://160.238.86.82:8003/#/index
api
hash 的值爲:#/index
瀏覽器
特色:hash 雖然出如今 URL 中,但不會被包括在 HTTP 請求中,對後端徹底沒有影響,所以改變 hash 不會從新加載頁面服務器
pushState()
和 replaceState()
方法這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forword、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會當即向後端發送請求app
所以能夠說,hash 模式和 history 模式都屬於瀏覽器自身的特性,Vue-Router 只是利用了這兩個特性(經過調用瀏覽器提供的接口)來實現前端路由框架
使用場景code
通常場景下,hash 和 history 均可以htm
若是不想用 hash 的話,那麼就可使用路由的history 模式,這種模式充分利用 history.pushState API 來完成
URL 跳轉而無須從新加載頁面
另外,調用 history.pushState()
想比於直接修改 hash
存在一下優點:
pushState()設置的新 URL 能夠是與當前 URL 同源的任意URL;而 hash 只可修改 # 後面的部分,所以只能設置與當前 URL 同文檔的 URL;
pushState() 設置的新 URL 能夠與當前 URL 如出一轍,這樣也會把記錄添加到棧中;而 hash 設置的新值必須與原來不同纔會觸發動做將記錄添加到棧中;
pushState() 經過 stateObject 參數能夠添加任意類型的數據到記錄中;而 hash 只可添加短字符串;
pushState() 可額外設置 title 屬性供後續使用。
固然 history 也不是碾壓 hash ,SPA 雖然在瀏覽器裏遊刃有餘,但真要經過 URL 向後端發起 HTTP 請求時,二者的差別就來了。尤爲在用戶手動輸入 URL 後回車,或者刷新(重啓)瀏覽器的時候
hash 模式下,僅 hash 符號以前的內容會被包含在請求中,如: http://160.238.86.82:8003
所以對於後端來講,即便沒有作到對路由的全覆蓋,也不會返回 404 錯誤。
history 模式下,前端的 URL 必須和實際向後端發起請求的 URL 一致,如:http://160.238.86.82:8003/age/id
若是後端缺乏對/age/id 的路由處理,將返回 404 錯誤。
不過這種模式要玩好,還須要後臺配置支持……因此,你要在服務端增長一個覆蓋全部狀況的候選資源:若是 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。
history模式怕什麼呢?
經過history api,咱們丟掉了醜陋的#,可是它也有個毛病:
不怕前進,不怕後退,就怕刷新,f5,(若是後端沒有準備的話),由於刷新是實實在在地去請求服務器的,不玩虛的。
而在hash模式下,前端路由修改的是#中的信息,而瀏覽器請求時是不帶它玩的,因此沒有問題.可是在history下,你能夠自由的修改path,當刷新時,若是服務器中沒有相應的響應或者資源,會分分鐘刷出一個404來。
總結
結合自身狀況,對於通常的 Vue + Vue-Router + Webpack + XXX 形式的 Web 開發場景,用 history 模式便可,只需在後端(Apache 或 Nginx)進行簡單的路由配置,同時搭配前端路由的 404 頁面支持就萬事大吉嘍。