1.什么是路由
簡單舉例說明,假如我們有一臺提供 Web 服務的服務器的網絡地址是:10.0.0.1,而該 Web 服務又提供了三個可供用戶訪問的頁面,其頁面 URI 分別是:
http://10.0.0.1/
http://10.0.0.1/about
http://10.0.0.1/concat
那么其路徑就分別是 /,/about,/concat。
當用戶使用 http://10.0.0.1/about 來訪問該頁面時,Web 服務會接收到這個請求,然后會解析 URL 中的路徑 /about,在 Web 服務的程序中,該路徑對應著相應的處理邏輯,程序會把請求交給路徑所對應的處理邏輯,這樣就完成了一次「路由分發」,這個分發就是通過「路由」來完成的。
以前路由都是后臺做的,通過用戶請求的url導航到具體的html頁面,前端路由就是通過配置js文件,把這個工作拿到前端來做。
簡單的說,路由是根據不同的 url 地址展示不同的內容或頁面
2.前端路由
前端的路由和后端的路由在實現技術上不一樣,但是原理都是一樣的。在 HTML5 的 history API 出現之前,前端的路由都是通過 hash 來實現的,hash 能兼容低版本的瀏覽器。如果我們把上面例子中提到的 3 個頁面用 hash 來實現的話,它的 URI 規則中需要帶上 #。
1http://10.0.0.1/2http://10.0.0.1/#/about3http://10.0.0.1/#/concat
Web 服務并不會解析 hash,也就是說 # 后的內容 Web 服務都會自動忽略,但是 JavaScript 是可以通過 window.location.hash 讀取到的,讀取到路徑加以解析之后就可以響應不同路徑的邏輯處理。
history 是 HTML5 才有的新 API,可以用來操作瀏覽器的 session history。基于 history 來實現的路由可以和最初的例子中提到的路徑規則一樣。
1http://10.0.0.1/2http://10.0.0.1/about3http://10.0.0.1/concat
具體如何實現前端路由將在后面的文章中介紹。
3.前端路由的使用場景?
前端路由更多用在單頁應用上, 也就是SPA, 因為單頁應用, 基本上都是前后端分離的, 后端自然也就不會給前端提供路由。
4.前端路由優缺點
優點:
1.從性能和用戶體驗的層面來比較的話,后端路由每次訪問一個新頁面的時候都要向服務器發送請求,然后服務器再響應請求,這個過程肯定會有延遲。而前端路由在訪問一個新頁面的時候僅僅是變換了一下路徑而已,沒有了網絡延遲,對于用戶體驗來說會有相當大的提升。
2.在某些場合中,用ajax請求,可以讓頁面無刷新,頁面變了但Url沒有變化,用戶就不能復制到想要的地址,用前端路由做單頁面網頁就很好的解決了這個問題
缺點:
使用瀏覽器的前進,后退鍵的時候會重新發送請求,沒有合理地利用緩存。
1、路由就是用來跟后端服務器進行交互的一種方式,通過不同的路徑,來請求不同的資源,請求不同的頁面是路由的其中一種功能。
if(path='./xxx'){
? ? do something
}
2、路由實現的兩種方式
在現在這些MVC和MVVM框架興起之前,是不存在前端路由的,頁面之間的跳轉是由后臺控制的。隨著前后端分離和單頁面應用(SPA)的興起和WEB項目復雜度的增加,再加上前面這些框架的支持,慢慢前端路由也就成為了現實。單頁面應用的特點就是可以在改變URL在不重新請求頁面的情況下更新頁面視圖。
"更新視圖但不重新請求頁面"是前端路由的原理的核心之一,目前在瀏覽器環境中這一功能的實現主要有兩種方式
利用URL中的hash("#")
利用History interface在 HTML5中新增的方法
hash
這是的hash不是指的是數據結構中的hash表,而是類似https://juejin.im/#123gqwf,通過監聽a標簽,這樣#號后面值的變化并不會發送請求也不會刷新頁面,并且會觸發windo.onhashchange事件。
pushState
html5新增加的api,History.pushState()History.replaceState(),這兩個api也能改變url并且不發送請求,而且比#好看,原理也是相同的,但是如果用戶刷新頁面,也會發送請求,返回404,所以需要后端配合,如果用戶刷新頁面,把所有的無響應的路由重定向到根目錄
3、vue-router實現前端路由的方法和對比
在vue-router中有mode這樣一個參數,這個參數的可選值有"hash"、 "history"、"abstract"
const router = new VueRouter({
? mode: 'history',
? routes: [...]
})
那"hash"和"history"這兩種方式各有什么優劣呢?
首先在vue-router中默認使用的是hash這種方式,因為這種方式雖然帶個#有點丑(官方竟然都這樣說),但是不存在兼容性問題
而history由于底層的實現根據MDN的介紹,調用history.pushState(),所以存在瀏覽器兼容性問題。
如果不考慮兼容性問題的話,pushState肯定比只修改hash值更加強大,因為可以設置任意同源URL
pushState可以設置和當前URL一模一樣,這樣也會把記錄添加到棧中,而hash設置的新值必須和原來不一樣
還有,就算不考慮兼容問題的話,history模式還有一個問題,就是history模式會將URL修改的和正常請求后端的URL一樣
http://oursite.com/user/id
這樣的話如果后端沒有配置對應的user/id這樣一個地址的話就會返回404,官方推薦的解決辦法是在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。同時這么做以后,服務器就不再返回 404 錯誤頁面,因為對于所有路徑都會返回 index.html 文件。為了避免這種情況,在 Vue 應用里面覆蓋所有的路由情況,然后在給出一個 404 頁面。(這種方案我還沒實踐過,有機會要實踐一下)
所以綜合考慮來說用在一些中后臺項目中的話一般直接就采用hash這種默認方式了,而前臺項目的話看需求選擇使用history還是hash