Vue Router中hash模式和history模式的區別

面試問答

    hash 模式與 history 模式的區別,這個也是面試常問的問題,不要小看這道題其實問到這裏的時候那個面試官應該是個大牛,開發經驗豐富,這個題其實就是考驗你的開發經驗是否屬實。

    小白回答: hash 模式 url 帶 # 號,history 模式不帶 # 號。

    大牛解答: hash 模式 url 裏面永遠帶着 # 號,我們在開發當中默認使用這個模式。那麼什麼時候要用 history 模式呢?如果用戶考慮 url 的規範那麼就需要使用 history 模式,因爲 history 模式沒有#號,是個正常的 url 適合推廣宣傳。當然其功能也有區別,比如我們在開發 app 的時候有分享頁面,那麼這個分享出去的頁面就是用 vue 或是 react 做的,咱們把這個頁面分享到第三方的 app 裏,有的 app 裏面 url 是不允許帶有 # 號的,所以要將#號去除那麼就要使用 history 模式,但是使用 history 模式還有一個問題就是,在訪問二級頁面的時候,做刷新操作,會出現404錯誤,那麼就需要和後端人配合讓他配置一下 apache 或是 nginx 的 url 重定向,重定向到你的首頁路由上就OK啦。

模式

    Vue 爲了構建 SPA, 需要引入前端路由系統 Vue-Router。前端路由的核心,就在於 —— 改變視圖的同時不會向後端發送請求。爲了達到這一目的,瀏覽器當前提供了以下兩種支持:

    1. hash —— 即地址欄 URL 中的 # 符號(此 hash 不是密碼學裏的散列運算)

    比如這個 URL:http://www.abc.com/#/hello,hash 的值爲 #/hello。它的特點在於:hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對後端完全沒有影響,因此改變 hash 不會重新加載頁面

    2. history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法(需要特定瀏覽器支持)

    這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向後端發送請求

    因此可以說,hash 模式和 history 模式都屬於瀏覽器自身的特性,Vue-Router 只是利用了這兩個特性(通過調用瀏覽器提供的接口)來實現前端路由

使用場景

    一般場景下,hash 和 history 都可以,如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成,URL 跳轉而無須重新加載頁面。

    另外,根據 Mozilla Develop Network 的介紹,調用 history.pushState() 相比於直接修改 hash,存在以下優勢:

    1. pushState() 設置的新 URL 可以是與當前 URL 同源的任意 URL;而 hash 只可修改 # 後面的部分,因此只能設置與當前 URL 同文檔的 URL

    2. pushState() 設置的新 URL 可以與當前 URL 一模一樣,這樣也會把記錄添加到棧中;而 hash 設置的新值必須與原來不一樣纔會觸發動作將記錄添加到棧中

    3. pushState() 通過 stateObject 參數可以添加任意類型的數據到記錄中;而 hash 只可添加短字符串

    4. pushState() 可額外設置 title 屬性供後續使用

History模式下的問題

    但是當用戶手動輸入 URL 後回車,或者刷新(重啓)瀏覽器的時候,會出現以下問題:

    1. hash 模式下,僅 hash 符號之前的內容會被包含在請求中,如 http://www.abc.com,因此對於後端來說,即使沒有做到對路由的全覆蓋,也不會返回 404 錯誤

    2. 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 頁面支持。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章