1. 程式人生 > 其它 >前端路由hash、history模式的區別及簡單實現

前端路由hash、history模式的區別及簡單實現

技術標籤:Javascript前端javascripthtml5vue.js

一、什麼是路由?

路由是根據不同的url地址來顯示不同的頁面或內容。
當我們訪問一個url地址的時候,大致流程可以想象成這樣:

  1. 瀏覽器向伺服器發出請求;
  2. 伺服器監聽到80埠,如果有請求,那麼就解析url地址。
  3. 伺服器根據路由配置,然後就返回相應的資訊(比如html字串、json資料或圖片等)。
  4. 瀏覽器根據伺服器響應的Content-Type來決定如何解析資料。

以上就是傳統路由最初始的實現方式,缺點是每次路由切換都需要重新整理頁面,發ajax請求,然後把資料返回回來,這樣對使用者體驗就不好了
因此為了提升使用者體驗,前端路由就產生了,它就可以解決瀏覽器不會重新重新整理了。

在瞭解路由之前,先簡單的看一下history api有哪些方法:

> window.history.length: 返回當前會話瀏覽的頁面數量;
> window.history.go(): 接收一個整數作為引數,按照當前頁面在會話瀏覽歷史記錄中的位置進行移動;
> window.history.back(): 移動到上一頁。相當於點選瀏覽器的後退按鈕;
> window.history.forward(): 移動到下一頁,相當於點選瀏覽器的前進按鈕;
> window.history.pushState(): 在會話瀏覽歷史記錄中新增一條記錄;
> window.history.replaceState(): 該方法用法和history.pushState方法類似,但是該方法的含義是將修改會話瀏覽歷史的當前記錄,而不是新增一條記錄。

有了這些基本知識後,我們再來看下前端路由,前端路由也有2種模式,第一種是hash模式,第二種是history模式。我們來分別看下這兩種知識點及區別如下:

二、hash模式

hash路由模式是這樣的:http://xxx.com/#/xx。 帶#號,後面就是hash值的變化。實現hash路由的基本條件:

  1. url中hash值的改變,並不會重新載入頁面;
  2. hash值的改變會在瀏覽器的訪問歷史中增加一條記錄,可以通過瀏覽器的後退,前進按鈕控制hash值的切換;
  3. 可以通過hashchange事件,監聽到hash值的變化,從而載入不同的頁面顯示。

示例:

<!DOCTYPE html>
<html
lang="en">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>hash test</title> </head> <body> <p>hash test</p> <button id="btn">修改 hash</button> <script> // hash 變化,包括: // a. JS 修改 url // b. 手動修改 url 的 hash // c. 瀏覽器前進、後退 window.onhashchange = (event) => { console.log('old url', event.oldURL) console.log('new url', event.newURL) console.log('hash:', location.hash) } // 頁面初次載入,獲取 hash // 當初始的 HTML 文件被完全載入和解析完成之後,DOMContentLoaded 事件被觸發 document.addEventListener('DOMContentLoaded', () => { console.log('hash:', location.hash) }) // JS 修改 url document.getElementById('btn').addEventListener('click', () => { location.href = '#/user' }) </script> </body> </html>

三、history模式

  • 用url規範的路由,但跳轉時不重新整理頁面;
  • window.history.pushState 能修改路徑、查詢引數和片段識別符號。pushState比hash更符合前端路由的訪問方式,更加優雅(因為不帶#號);
  • window.onpopstate來監聽歷史棧的改變,只要歷史棧有資訊發生改變的話,就會觸發該事件。

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>history API test</title>
</head>
<body>
    <p>history API test</p>
    <button id="btn">修改 url</button>

    <script>
        // 頁面初次載入,獲取 path
        document.addEventListener('DOMContentLoaded', () => {
            console.log('load', location.pathname)
        })

        // 開啟一個新的路由
        // 【注意】用 pushState 方式,瀏覽器不會重新整理頁面
        document.getElementById('btn').addEventListener('click', () => {
            const state = { name: 'page1' }
            console.log('切換路由到', 'page1')
            history.pushState(state, '', 'page1') // 重要!!!
        })

        // 監聽瀏覽器前進、後退
        window.onpopstate = (event) => { // 重要!!!
            console.log('onpopstate', event.state, location.pathname)
        }
    </script>
</body>
</html>

需要 server 端配合,可參考
https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90

四、總結

傳統的路由指的是:當用戶訪問一個url時,對應的伺服器會接收這個請求,然後解析url中的路徑,從而執行對應的處理邏輯。這樣就完成了一次路由分發。

而前端路由是不涉及伺服器的,是前端利用hash或者HTML5的history API來實現的,一般用於不同內容的展示和切換。