history與hash路由的區別

西芹兒發表於2018-06-26

hash前端路由,無重新整理

history   會去請求介面

vue-router提供兩種模式的原因:

vue 是漸進式前端開發框架,為了實現 SPA ,需要引入前端路由系統(vue-router)。前端路由的核心是:改變檢視的同時不會向後端發出請求。

為了達到這一目的,瀏覽器提供了 hash 和 history 兩種模式。

  1. hash :hash 雖然出現在 URL 中,但不會被包含在 http 請求中,對後端完全沒有影響,因此改變 hash 不會重新載入頁面。
  2. history :history 利用了 html5 history interface 中新增的 pushState() 和 replaceState() 方法。這兩個方法應用於瀏覽器記錄棧,在當前已有的 back、forward、go 基礎之上,它們提供了對歷史記錄修改的功能。只是當它們執行修改時,雖然改變了當前的 URL ,但瀏覽器不會立即向後端傳送請求。

因此可以說, hash 模式和 history 模式都屬於瀏覽器自身的屬性,vue-router 只是利用了這兩個特性(通過呼叫瀏覽器提供的介面)來實現路由。

實現的原理:

  1. hash 模式的原理是 onhashchange 事件,可以在 window 物件上監聽這個事件。
  2. history :hashchange 只能改變 # 後面的程式碼片段,history api (pushState、replaceState、go、back、forward) 則給了前端完全的自由,通過在window物件上監聽popState()事件。
pushState()、replaceState() 方法接收三個引數:stateObj、title、url。

// 設定狀態
history.pushState({color: "red"}, "red", "red");

// 監聽狀態
window.onpopstate = function(event){
    console.log(event.state);
    if(event.state && event.state.color === "red"){
        document.body.style.color = "red";
    }
}

// 改變狀態
history.back();
history.forward();複製程式碼

應用場景:

通過 pushState 把頁面的狀態儲存在 state 物件中,當頁面的 url 再變回到這個 url 時,可以通過 event.state 取到這個 state 物件,從而可以對頁面狀態進行還原,如頁面滾動條的位置、閱讀進度、元件的開關等。

呼叫 history.pushState() 比使用 hash 存在的優勢:

  • pushState 設定的 url 可以是同源下的任意 url ;而 hash 只能修改 # 後面的部分,因此只能設定當前 url 同文件的 url
  • pushState 設定的新的 url 可以與當前 url 一樣,這樣也會把記錄新增到棧中;hash 設定的新值不能與原來的一樣,一樣的值不會觸發動作將記錄新增到棧中
  • pushState 通過 stateObject 引數可以將任何資料型別新增到記錄中;hash 只能新增短字串
  • pushState 可以設定額外的 title 屬性供後續使用

劣勢:

  • history 在重新整理頁面時,如果伺服器中沒有相應的響應或資源,就會出現404。因此,如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面
  • hash 模式下,僅 # 之前的內容包含在 http 請求中,對後端來說,即使沒有對路由做到全面覆蓋,也不會報 404

參考:https://blog.csdn.net/majunjie2017/article/details/78507551


相關文章