hash和history路由的區別

愛喝酸奶的吃貨發表於2022-05-31

在瞭解路由模式前,我們先看下 什麼是單頁面應用,vue-router  的實現原理是怎樣的,這樣更容易理解路由。

SPA與前端路由

SPA(單頁面應用,全程為:Single-page Web applications)指的是隻有一張Web頁面的應用,是載入單個HTML 頁面並在使用者與應用程式互動時動態更新該頁面的Web應用程式,簡單通俗點就是在一個專案中只有一個html頁面,它在第一次載入頁面時,將唯一完成的html頁面和所有其餘頁面元件一起下載下來,所有的元件的展示與切換都在這唯一的頁面中完成,這樣切換頁面時,不會重新載入整個頁面,而是通過路由來實現不同元件之間的切換。

單頁面應用(SPA)的核心之一是:更新檢視而不重新請求頁面。

vue Router實現原理

vue-router  在實現單頁面路由時,提供了兩種方式:Hash  模式和  History  模式;vue2是 根據  mode  引數來決定採用哪種方式,預設是  Hash  模式,手動設定為  History  模式。更新檢視但不重新請求頁面”是前端路由原理的核心之一,目前在瀏覽器環境中這一功能的實現主要有以下兩種方式

Hash

簡述

  • vue-router   預設為hash模式,使用URL的  hash  來模擬一個完整的URL,當URL改變時,頁面不會重新載入;#  就是  hash符號,中文名為雜湊符或者錨點,在  hash  符號後的值稱為  hash  值。
  • 路由的  hash  模式是利用了  window可以監聽onhashchange 事件來實現的,也就是說  hash  值是用來指導瀏覽器動作的,對伺服器沒有影響,HTTP 請求中也不會包括  hash  值,同時每一次改變  hash  值,都會在瀏覽器的訪問歷史中增加一個記錄,使用“後退”按鈕,就可以回到上一個位置。所以,hash模式 是根據  hash 值  來發生改變,根據不同的值,渲染指定DOM位置的不同資料。
參考:Vue 前端路由工作原理,hash與history之間的區別

 特點

  • url中帶一個   #   號
  • 可以改變URL,但不會觸發頁面重新載入(hash的改變會記錄在  window.hisotry  中)因此並不算是一次http請求,所以這種模式不利於SEO優化
  • 只能修改  #  後面的部分,因此只能跳轉與當前URL同文件的URL
  • 只能通過字串改變URL
  • 通過  window.onhashchange  監聽  hash  的改變,藉此實現無重新整理跳轉的功能。
  • 每改變一次  hash ( window.location.hash),都會在瀏覽器的訪問歷史中增加一個記錄。
  • 路徑中從  開始,後面的所有路徑都叫做路由的  雜湊值並且雜湊值它不會作為路徑的一部分隨著http請求,發給伺服器
參考:在SPA專案的路由中,注意hash與history的區別

 History

簡述

  • history  是路由的另一種模式,在相應的  router  配置時將  mode  設定為  history  即可。
  • history  模式是通過呼叫  window.history  物件上的一系列方法來實現頁面的無重新整理跳轉。
  • 利用了 HTML5 History Interface  中新增的   pushState()  和  replaceState()  方法。
  • 這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的  back、forward、go  的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向後端傳送請求。

 參考:深入瞭解前端路由 hash 與 history 差異

特點

  • 新的URL可以是與當前URL同源的任意 URL,也可以與當前URL一樣,但是這樣會把重複的一次操作記錄到棧中。
  • 通過引數stateObject可以新增任意型別的資料到記錄中。
  • 可額外設定title屬性供後續使用。
  • 通過pushState、replaceState實現無重新整理跳轉的功能。
  • 路徑直接拼接在埠號後面,後面的路徑也會隨著http請求發給伺服器,因此前端的URL必須和向傳送請求後端URL保持一致,否則會報404錯誤。
  • 由於History API的緣故,低版本瀏覽器有相容行問題。
參考:在SPA專案的路由中,注意hash與history的區別前端框架路由實現的Hash和History兩種模式的區別

 生產環境存在問題

       因為  history  模式的時候路徑會隨著  http 請求傳送給伺服器,專案打包部署時,需要後端配置 nginx,當應用通過  vue-router  跳轉到某個頁面後,因為此時是前端路由控制頁面跳轉,雖然url改變,但是頁面只是內容改變,並沒有重新請求,所以這套流程沒有任何問題。但是,如果在當前的頁面重新整理一下,此時會重新發起請求,如果  nginx  沒有匹配到當前url,就會出現404的頁面。

那為什麼hash模式不會出現這個問題呢?
       上文已講,hash 雖然可以改變URL,但不會被包括在  HTTP  請求中。它被用來指導瀏覽器動作,並不影響伺服器端,因此,改變  hash  並沒有改變URL,所以頁面路徑還是之前的路徑,nginx  不會攔截。 因此,切記在使用  history  模式時,需要服務端允許地址可訪問,否則就會出現404的尷尬場景。

 那為什麼開發環境時就不會出現404呢?

因為在 vue-cli  中  webpack  幫我們做了處理

 

 解決問題

生產環境 重新整理 404 的解決辦法可以在 nginx 做代理轉發,在 nginx 中配置按順序檢查引數中的資源是否存在,如果都沒有找到,讓  nginx  內部重定向到專案首頁。

 參考:Vue 瞭解前端路由 hash 與 history 差異

 

相關文章