[轉(zhuǎn)帖]路由的兩種模式:hash模式和 history模式
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
為什么要使用路由現(xiàn)在的網(wǎng)絡(luò)應(yīng)用程序越來(lái)越多的使用AJAX異步請(qǐng)求完成頁(yè)面的無(wú)縫刷新,導(dǎo)致瀏覽器的URL不會(huì)發(fā)生任何變化而完成了請(qǐng)求,從而破換了用戶瀏覽體驗(yàn)。同時(shí)本次瀏覽的頁(yè)面內(nèi)容在用戶下次使用URL訪問(wèn)時(shí)將無(wú)法重新呈現(xiàn),使用路由可以很好地解決這個(gè)問(wèn)題。 單頁(yè)面應(yīng)用利用了Javascript動(dòng)態(tài)變換網(wǎng)頁(yè)內(nèi)容,避免了頁(yè)面重載;路由則提供了瀏覽器地址變化,網(wǎng)頁(yè)內(nèi)容也跟隨變化,兩者結(jié)合起來(lái)則為我們提供了體驗(yàn)良好的單頁(yè)面web應(yīng)用。 前端路由實(shí)現(xiàn)方式路由需要實(shí)現(xiàn)三個(gè)功能:
在單頁(yè)面web網(wǎng)頁(yè)中, 單純的瀏覽器地址改變, 網(wǎng)頁(yè)不會(huì)重載,如單純的hash網(wǎng)址改變網(wǎng)頁(yè)不會(huì)變化,因此我們的路由主要是通過(guò)監(jiān)聽(tīng)事件,并利用js實(shí)現(xiàn)動(dòng)態(tài)改變網(wǎng)頁(yè)內(nèi)容,有兩種實(shí)現(xiàn)方式:
hash模式使用window.location.hash屬性及窗口的onhashchange事件,可以實(shí)現(xiàn)監(jiān)聽(tīng)瀏覽器地址hash值變化,執(zhí)行相應(yīng)的js切換網(wǎng)頁(yè)。下面具體介紹幾個(gè)使用過(guò)程中必須理解的要點(diǎn):
觸發(fā)hashchange事件的幾種情況瀏覽器地址欄散列值的變化(包括瀏覽器的前進(jìn)、后退)會(huì)觸發(fā) 當(dāng)瀏覽器地址欄中URL包含哈希如 www.baidu.com/#home,這時(shí)按下輸入,瀏覽器發(fā)送www.baidu.com/,請(qǐng)求至服務(wù)器,請(qǐng)求完畢之后設(shè)置散列值為 當(dāng)只改變?yōu)g覽器地址欄URL的哈希部分,這時(shí)按下回車(chē),瀏覽器不會(huì)發(fā)送任何請(qǐng)求至服務(wù)器,這時(shí)發(fā)生的只是設(shè)置散列值新修改的哈希值,并觸發(fā)onhashchange事件; html中 //設(shè)置 url 的 hash,會(huì)在當(dāng)前url后加上'#abc' window.location.hash='abc'; let hash = window.location.hash //'#abc' window.addEventListener('hashchange',function(){ //監(jiān)聽(tīng)hash變化,點(diǎn)擊瀏覽器的前進(jìn)后退會(huì)觸發(fā) }) history模式概述
屬性History 對(duì)象主要有兩個(gè)屬性。
// 當(dāng)前窗口訪問(wèn)過(guò)多少個(gè)網(wǎng)頁(yè) history.length // 1 // History 對(duì)象的當(dāng)前狀態(tài) // 通常是 undefined,即未設(shè)置 history.state // undefined 方法
history.back(); history.forward(); history.go(1);//相當(dāng)于history.forward() history.go(-1);//相當(dāng)于history.back() history.go(0); // 刷新當(dāng)前頁(yè)面 注意:移動(dòng)到以前訪問(wèn)過(guò)的頁(yè)面時(shí),頁(yè)面通常是從瀏覽器緩存之中加載,而不是重新要求服務(wù)器發(fā)送新的網(wǎng)頁(yè)。 History.pushState()該方法用于在歷史中添加一條記錄。 語(yǔ)法: 該方法接受三個(gè)參數(shù),依次為:
var data = { foo: 'bar' }; history.pushState(data, '', '2.html'); console.log(history.state) // {foo: "bar"} 注意:如果 pushState 的 URL 參數(shù)設(shè)置了一個(gè)新的錨點(diǎn)值(即 hash),并不會(huì)觸發(fā) hashchange 事件。反過(guò)來(lái),如果 URL 的錨點(diǎn)值變了,則會(huì)在 History 對(duì)象創(chuàng)建一條瀏覽記錄。 如果 pushState() 方法設(shè)置了一個(gè)跨域網(wǎng)址,則會(huì)報(bào)錯(cuò)。 // 報(bào)錯(cuò) // 當(dāng)前網(wǎng)址為 http://example.com history.pushState(null, '', 'https://twitter.com/hello'); 上面代碼中,pushState 想要插入一個(gè)跨域的網(wǎng)址,導(dǎo)致報(bào)錯(cuò)。這樣設(shè)計(jì)的目的是,防止惡意代碼讓用戶以為他們是在另一個(gè)網(wǎng)站上,因?yàn)檫@個(gè)方法不會(huì)導(dǎo)致頁(yè)面跳轉(zhuǎn)。 History.replaceState()該方法用來(lái)修改 History 對(duì)象的當(dāng)前記錄,用法與 pushState() 方法一樣。 假定當(dāng)前網(wǎng)頁(yè)是 example.com/example.htm… history.pushState({page: 1}, '', '?page=1') // URL 顯示為 http://example.com/example.html?page=1 history.pushState({page: 2}, '', '?page=2'); // URL 顯示為 http://example.com/example.html?page=2 history.replaceState({page: 3}, '', '?page=3'); // URL 顯示為 http://example.com/example.html?page=3 history.back() // URL 顯示為 http://example.com/example.html?page=1 history.back() // URL 顯示為 http://example.com/example.html history.go(2) // URL 顯示為 http://example.com/example.html?page=3 popstate 事件每當(dāng) history 對(duì)象出現(xiàn)變化時(shí),就會(huì)觸發(fā) popstate 事件。 注意:
使用的時(shí)候,可以為popstate事件指定回調(diào)函數(shù),回調(diào)函數(shù)的參數(shù)是一個(gè) event 事件對(duì)象,它的 state 屬性指向當(dāng)前的 state 對(duì)象。 window.addEventListener('popstate', function(e) { //e.state 相當(dāng)于 history.state console.log('state: ' + JSON.stringify(e.state)); console.log(history.state); }); 通過(guò)history.pushState 實(shí)現(xiàn)頁(yè)面 tab 切換的功能。 history 致命的缺點(diǎn)就是當(dāng)改變頁(yè)面地址后,強(qiáng)制刷新瀏覽器時(shí),(如果后端沒(méi)有做準(zhǔn)備的話)會(huì)報(bào)錯(cuò),因?yàn)樗⑿率悄卯?dāng)前地址去請(qǐng)求服務(wù)器的,如果服務(wù)器中沒(méi)有相應(yīng)的響應(yīng),會(huì)出現(xiàn) 404 頁(yè)面。 —————————————————— https://juejin.cn/post/7236563012533878821 該文章在 2023/5/30 9:08:08 編輯過(guò) |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |