hash和history兩種模式的區別


hash和history兩種模式的區別


 

vue-router(前端路由)有兩種模式,hash模式和history模式,這里來談談兩者的區別。

  1. hash 就是指 url 尾巴后的 # 號以及后面的字符,history沒有底帶#,外觀上比hash 模式好看些
  2. hash回車刷新會加載到地址欄對應的頁面,history一般就是404掉了
  3.  hash 能兼容到IE8, history 只能兼容到 IE10;
  4. 由於 hash 值變化不會導致瀏覽器向服務器發出請求,而且 hash 改變會觸發 hashchange 事件(hashchange只能改變 # 后面的url片段);雖然hash路徑出現在URL中,但是不會出現在HTTP請求中,對后端完全沒有影響,因此改變hash值不會重新加載頁面,基本都是使用 hash 來實現前端路由的。

(因為Vue項目是個單頁客戶端應用,如果后台沒有正確的配置,當用戶在瀏覽器直接訪問 http://localhost:8080/user/id 就會返回 404,這就不好看了。history 模式改變 url 的方式會導致瀏覽器向服務器發送請求,這不是我們想看到的,我們需要在服務器端做處理:如果匹配不到任何靜態資源,則應該始終返回同一個 html 頁面)

    history模式URL就要和后端進行一致,所以要改為history也需要后端的配合,否則會報錯。
所以hash模式在每次刷新頁面時是直接更改“#”后的東西,history每次刷新會重新像后端請求整個網址,也就是重新請求服務器。如果后端沒有及時響應,就會報錯404!。history的好處是可以進行修改歷史記錄,並且不會立刻像后端發起請求。不過如果對於項目沒有硬性標准要求,我們可以直接使用hash模式開發。

  5.原理區別

  hash原理:hash通過監聽瀏覽器的onhashchange()事件變化,查找對應的路由規則

  history原理: 利用H5的 history中新增的兩個API pushState() 和 replaceState() 和一個事件onpopstate監聽URL變化

  1. history模式
    利用了HTML5 History Interface中新增的pushState()和replaceState()方法,這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的back、forward、go的基礎上,他們提供了對當前瀏覽器進行修改的功能,只是當它們被修改時,雖然瀏覽器的URL發生
    了變化,但是不會立即向后端服務器發送請求,但是如果點擊刷新,就會重新向后端服務器發送請求。
  2. 使用場景
    一般情況下,vue-router前端路由模式使用history和hash都可以,在美觀上history比hash美觀些,因為hash有自己的特定符號#
    相比於hash,history具有以下優勢:
    *pushState()設置新的URL可以是任意與當前URL同源的URL,而hash只能改變#后面的內容,因此只能設置與當前URL同文檔的URL
    *pushState()設置的URL與當前URL一模一樣時也會被添加到歷史記錄棧中,而hash模式中,#后面的內容必須被修改才會被添加到新的記錄棧中
    *pushState()可以通過stateObject參數添加任意類型的數據到記錄中,而hash只能添加短字符串
    *pushState()可額外設置title屬性供后續使用

四、為什么要有hash和history?

對於 Vue 這類漸進式前端開發框架,為了構建 SPA(單頁面應用),需要引入前端路由系統,這也就是 Vue-Router 存在的意義。前端路由的核心,就在於 —— 改變視圖的同時不會向后端發出請求。

為了達到這一目的,瀏覽器當前提供了以下兩種支持:

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

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

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

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

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

 

如何使用history模式:(在vue項目的路由配置`src/router/index.js`里面配置)

new Router({

//去掉地址中的哈希#

mode:"history", // 還需要后台做一些配合

 

五、使用場景:

一般場景下,hash 和 history 都可以,除非你更在意顏值,# 符號夾雜在 URL 里看起來確實有些不太美麗。

如果不想要很丑的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成

URL 跳轉而無須重新加載頁面。—— Vue-router 官網

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

  • pushState() 設置的新 URL 可以是與當前 URL 同源的任意 URL;而 hash 只可修改 #后面的部分,因此只能設置與當前 URL 同文檔的 URL;
  • pushState() 設置的新 URL 可以與當前 URL 一模一樣,這樣也會把記錄添加到棧中;而 hash 設置的新值必須與原來不一樣才會觸發動作將記錄添加到棧中;
  • pushState() 通過 stateObject 參數可以添加任意類型的數據到記錄中;而 hash只可添加短字符串;
  • pushState() 可額外設置 title 屬性供后續使用。

當然啦,history 也不是樣樣都好。SPA 雖然在瀏覽器里游刃有余,但真要通過 URL 向后端發起 HTTP 請求時,兩者的差異就來了。尤其在用戶手動輸入 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 依賴的頁面。”


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM