浅谈前端路由原理hash和history
淺談前端路由原理hash和history
- 🎹序言
- 🎸一、前端路由原理
- 1、SPA
- 2、什么時候需要路由
- 🎷二、Hash模式
- 1、定義
- 2、網頁url組成部分
- (1)了解幾個url的屬性
- (2)演示
- 3、hash的特點
- 🎺三、History模式
- 1、定義
- 2、與hash的區別
- 3、history的API
- 4、history的特點
- 5、存在問題
- 6、兩者選擇
- 🎻四、結束語
- 🐣彩蛋 One More Thing
- 🏷?參考資料
- 🏷?番外篇
🎹序言
眾所周知, hash 和 history 在前端面試中是很常考的一道題目。在學習本文內容之前,周一對 hash 和 history 的認知可能就在 hash 的 url 里面多了個 # ,而 history 就不會。然后,我認知里還有一個是只有 history 才能做前后端分離,而 hash 跟前后端分離沒有關系。然而,現實是……
對于前端路由來說, hash 和 history 都可以用于前后端分離項目,且兩者有各自的特點和各自的使用場景,在使用過程中主要要了解當前項目所處的場景,以便于更好地判斷使用哪一種路由模式更佳。下面進入本文的講解~😜
🎸一、前端路由原理
1、SPA
SPA,即單頁面應用(Single Page Application)。所謂單頁 Web 應用,就是只有一張 Web 頁面的應用。單頁應用程序 (SPA) 是加載單個 HTML 頁面并在用戶與應用程序交互時動態更新該頁面的 Web 應用程序。瀏覽器一開始會加載必需的 HTML 、 CSS 和 JavaScript ,所有的操作都在這張頁面上完成,都由 JavaScript 來控制。
現如今,為了配合單頁面 Web 應用快速發展的節奏,各類前端組件化技術棧層出不窮。近幾年來,通過不斷的版本迭代, vue 和 react 兩大技術棧脫穎而出,成為當下最受歡迎的兩大技術棧。
2、什么時候需要路由
對于現代開發的項目來說,稍微復雜一點的 SPA ,都需要用到路由。而 vue-router 正是 vue 的路由標配,且 vue-router 有兩種模式: hash 和 history 。
下面就依據這兩種模式來進行一一講解。
🎷二、Hash模式
1、定義
hash 模式是一種把前端路由的路徑用井號 # 拼接在真實 url 后面的模式。當井號 # 后面的路徑發生變化時,瀏覽器并不會重新發起請求,而是會觸發 onhashchange 事件。
2、網頁url組成部分
(1)了解幾個url的屬性
| location.protocal | 協議 |
| location.hostname | 主機名 |
| location.host | 主機 |
| location.port | 端口號 |
| location.patchname | 訪問頁面 |
| location.search | 搜索內容 |
| location.hash | 哈希值 |
(2)演示
下面用一個網址來演示以上屬性:
//http://127.0.0.1:8001/01-hash.html?a=100&b=20#/aaa/bbb location.protocal // 'http:' localtion.hostname // '127.0.0.1' location.host // '127.0.0.1:8001' location.port //8001 location.pathname //'01-hash.html' location.serach // '?a=100&b=20' location.hash // '#/aaa/bbb'3、hash的特點
-
hash變化會觸發網頁跳轉,即瀏覽器的前進和后退。
-
hash 可以改變 url ,但是不會觸發頁面重新加載(hash的改變是記錄在 window.history 中),即不會刷新頁面。也就是說,所有頁面的跳轉都是在客戶端進行操作。因此,這并不算是一次 http 請求,所以這種模式不利于 SEO 優化。hash 只能修改 # 后面的部分,所以只能跳轉到與當前 url 同文檔的 url 。
-
hash 通過 window.onhashchange 的方式,來監聽 hash 的改變,借此實現無刷新跳轉的功能。
-
hash 永遠不會提交到 server 端(可以理解為只在前端自生自滅)。
🎺三、History模式
1、定義
history API 是 H5 提供的新特性,允許開發者直接更改前端路由,即更新瀏覽器 URL 地址而不重新發起請求。
2、與hash的區別
我們用一個例子來演示, hash 與 history 在瀏覽器下刷新時的區別。具體如下:
正常頁面瀏覽
https://github.com/xxx 刷新頁面https://github.com/xxx/yyy 刷新頁面https://github.com/xxx/yyy/zzz 刷新頁面改造H5 history模式
https://github.com/xxx 刷新頁面https://github.com/xxx/yyy 前端跳轉,不刷新頁面https://github.com/xxx/yyy/zzz 前端跳轉,不刷新頁面3、history的API
下面闡述幾種 HTML5 新增的 history API 。具體如下表:
| history.pushState(data, title [, url]) | pushState主要用于往歷史記錄堆棧頂部添加一條記錄。各參數解析如下:①data會在onpopstate事件觸發時作為參數傳遞過去;②title為頁面標題,當前所有瀏覽器都會忽略此參數;③url為頁面地址,可選,缺少時表示為當前頁地址 |
| history.replaceState(data, title [, url]) | 更改當前的歷史記錄,參數同上; 上面的pushState是添加,這個更改 |
| history.state | 用于存儲以上方法的data數據,不同瀏覽器的讀寫權限不一樣 |
| window.onpopstate | 響應pushState或者replaceState的調用 |
4、history的特點
對于 history 來說,主要有以下特點:
- 新的 url 可以是與當前 url 同源的任意 url ,也可以是與當前 url 一樣的地址,但是這樣會導致的一個問題是,會把重復的這一次操作記錄到棧當中。
- 通過 history.state ,添加任意類型的數據到記錄中。
- 可以額外設置 title 屬性,以便后續使用。
- 通過 pushState 、 replaceState 來實現無刷新跳轉的功能。
5、存在問題
對于 history 來說,確實解決了不少 hash 存在的問題,但是也帶來了新的問題。具體如下:
- 使用 history 模式時,在對當前的頁面進行刷新時,此時瀏覽器會重新發起請求。如果 nginx 沒有匹配得到當前的 url ,就會出現 404 的頁面。
- 而對于 hash 模式來說, 它雖然看著是改變了 url ,但不會被包括在 http 請求中。所以,它算是被用來指導瀏覽器的動作,并不影響服務器端。因此,改變 hash 并沒有真正地改變 url ,所以頁面路徑還是之前的路徑, nginx 也就不會攔截。
- 因此,在使用 history 模式時,需要通過服務端來允許地址可訪問,如果沒有設置,就很容易導致出現 404 的局面。
6、兩者選擇
下面我們再來介紹下在實際的項目中,如何對這兩者進行選擇。具體如下:
- to B 的系統推薦用 hash ,相對簡單且容易使用,且因為 hash 對 url 規范不敏感;
- to C 的系統,可以考慮選擇 H5 history ,但是需要服務端支持;
- 能先用簡單的,就別用復雜的,要考慮成本和收益。
🎻四、結束語
對于 hash 和 history 來講,要清楚兩者的區別以及兩者各自的使用場景,還有各自的使用特點和優缺點。以上文章只是對前端路由原理的淺談,希望對大家有幫助~
另下方第三個彩蛋放了一篇關于實現 vue-router 的文章,學有余力的小伙伴有需要自取o!
🐣彩蛋 One More Thing
🏷?參考資料
jarvis👉在SPA項目的路由中,注意hash與history的區別
vue-router官方文檔👉vue-router的兩種模式
值得一看👉從使用到自己實現簡單Vue Router看這個就行了
🏷?番外篇
- 關注公眾號星期一研究室,第一時間關注優質文章,更多精選專欄待你解鎖~
- 如果這篇文章對你有用,記得留個腳印jio再走哦~
- 以上就是本文的全部內容!我們下期見!👋👋👋
總結
以上是生活随笔為你收集整理的浅谈前端路由原理hash和history的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦回十年前,消息称一加 12 手机将推出
- 下一篇: 斗牛游戏的基本游戏规则