這篇文章主要介紹前端路由指的是什么,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
主要從事網(wǎng)頁(yè)設(shè)計(jì)、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、響應(yīng)式網(wǎng)站建設(shè)、程序開(kāi)發(fā)、微網(wǎng)站、微信平臺(tái)小程序開(kāi)發(fā)等,憑借多年來(lái)在互聯(lián)網(wǎng)的打拼,我們?cè)诨ヂ?lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、網(wǎng)絡(luò)營(yíng)銷經(jīng)驗(yàn),集策劃、開(kāi)發(fā)、設(shè)計(jì)、營(yíng)銷、管理等多方位專業(yè)化運(yùn)作于一體,具備承接不同規(guī)模與類型的建設(shè)項(xiàng)目的能力。什么是前端路由
所謂的前端路由,擁有這樣一種能力:客戶端瀏覽器可以不依賴服務(wù)端,根據(jù)不同的URL渲染不同的視圖頁(yè)面。
在Ajax之劍還未亮出,前端仍處于襁褓之中的時(shí)候,路由的工作交給了后端。在進(jìn)行頁(yè)面切換的時(shí)候,瀏覽器發(fā)送不同的url
請(qǐng)求;服務(wù)器接收到瀏覽器的請(qǐng)求時(shí),通過(guò)解析不同的url
去拼接需要的html
或者模板,然后將結(jié)果返回給瀏覽器端進(jìn)行渲染。
服務(wù)器端路由也是不落俗套的有利亦有弊。它的好處是安全性更高,更嚴(yán)格得控制頁(yè)面的展現(xiàn)。這在某些場(chǎng)景中是很有用的,譬如下單支付流程,每一步只有在上一步成功執(zhí)行之后才能抵達(dá)。這在服務(wù)器端可以為每一步流程添加驗(yàn)證機(jī)制,只有驗(yàn)證通過(guò)才返回正確的頁(yè)面。那么前端路由不能實(shí)現(xiàn)每一步的驗(yàn)證?自然不是,姑且相信你的代碼可以寫(xiě)的很?chē)?yán)謹(jǐn),保證正常情況下流程不會(huì)錯(cuò),但是另一個(gè)不得不面對(duì)的事實(shí)是:前端是毫無(wú)安全性可言的。用戶可以肆意修改代碼來(lái)進(jìn)入不同的流程,你可能會(huì)為此添加不少的處理邏輯。相較之下,當(dāng)然是后端控制頁(yè)面的進(jìn)入權(quán)限更為安全和簡(jiǎn)便。
另一方面,后端路由無(wú)疑增加了服務(wù)器端的負(fù)荷,并且需要reload
頁(yè)面,用戶體驗(yàn)其實(shí)不佳。
這樣,前端路由就有用武之地了。首先,它的出現(xiàn)無(wú)疑減輕了服務(wù)器端的壓力。特別是對(duì)于一個(gè)比較復(fù)雜的應(yīng)用來(lái)講,或者更確切的說(shuō),對(duì)于擁有一個(gè)復(fù)雜路由系統(tǒng)的應(yīng)用來(lái)說(shuō),服務(wù)器端需要為每一個(gè)不同的url執(zhí)行一段處理邏輯在高并發(fā)的情況下實(shí)在有點(diǎn)不堪重負(fù);其次,頁(yè)面的切換可以不需要刷新整個(gè)頁(yè)面了,沒(méi)有網(wǎng)絡(luò)延遲,沒(méi)有閃爍刷新,提升了用戶體驗(yàn)。
既然目標(biāo)實(shí)現(xiàn),我們需要解決的問(wèn)題有哪些?我們可以將問(wèn)題拆的稍微細(xì)一點(diǎn),先制定一個(gè)億的小計(jì)劃,實(shí)現(xiàn)之后再進(jìn)行下一步:)
在頁(yè)面不刷新的前提下實(shí)現(xiàn)url
變化
捕捉到url
的變化,以便執(zhí)行頁(yè)面替換邏輯
url
并且頁(yè)面不刷新正如前面所說(shuō),前端路由相較于后端路由的一個(gè)特點(diǎn)就是頁(yè)面在不完全刷新的情況下進(jìn)行視圖的切換。頁(yè)面url
變了,但是并沒(méi)有重新加載!看上去似乎有點(diǎn)不可思議,其實(shí)也沒(méi)什么大不了。
試想將瀏覽器地址欄當(dāng)做一個(gè)輸入框,我們需要實(shí)現(xiàn)的就是改變輸入框的value
但是不觸發(fā)請(qǐng)求頁(yè)面的操作,這樣就不會(huì)重新加載新頁(yè)面。倘若輸入框的值的變化和發(fā)送請(qǐng)求是一個(gè)原子操作,我們也就束手無(wú)策了。慶幸的是,只有當(dāng)我們敲擊了回車(chē)之后,請(qǐng)求才會(huì)被發(fā)送出去(這是顯而易見(jiàn)的吧)。因此這就為我們修改地址欄的值而不觸發(fā)頁(yè)面請(qǐng)求刷新創(chuàng)造了條件。BOM是否有提供修改瀏覽器地址欄url
而不觸發(fā)請(qǐng)求操作的方法呢?
這里,存在兩種滿足需求的方式。一是利用url
中的hash
字段;二是使用HTML5提供的history API。
hash
方式了解http
協(xié)議就會(huì)知道,url
的組成部分有很多,譬如協(xié)議、主機(jī)名、資源路徑、查詢字段等等,其中包含一個(gè)稱之為片段的部分,以#
為標(biāo)識(shí)。
例如: http://www.gmail.com/text/#123
,123
便是url
中的hash
部分。
打開(kāi)控制臺(tái),輸入 location.hash
,你可以得到當(dāng)前url
的hash
部分(如果當(dāng)前url
不存在hash
則返回空字符串)。接下來(lái),輸入 location.hash = '123'
,會(huì)發(fā)現(xiàn)瀏覽器地址欄的url
變了,末尾增加了#123
字段,并且,頁(yè)面沒(méi)有被重新刷新。很顯然,這很符合我們的要求。
HTML5引入了一個(gè)history
對(duì)象,包含了一套訪問(wèn)瀏覽器歷史的API,可以通過(guò)window.history
訪問(wèn)到它。
這里我們看上了它的兩個(gè)API方法:pushState
和 replaceState
。
history.replaceState(dataObj, title, url); history.pushState(dataObj, title, url);
若上所示,它們接收完全相同的參數(shù),都是對(duì)瀏覽器的歷史棧進(jìn)行操作,將傳遞的url和相關(guān)數(shù)據(jù)壓棧,并將瀏覽器地址欄的url
替換成傳入的url
且不刷新頁(yè)面(正中下懷?。?。
By the way,不同的地方是
pushState
將指定的url
直接壓入歷史記錄棧頂,而replaceState
是將當(dāng)前歷史記錄棧頂替換成傳入的數(shù)據(jù)。
這兩種方式都可以幫我們滿足題設(shè)條件。采用哪一種方式除了主觀喜好之外,還得依照客觀事實(shí):低版本的瀏覽器對(duì)于history API的兼容性不好,例如遇到了IE8,擺在眼前的道路似乎就別無(wú)選擇了。
url
變化在瀏覽器端,跟蹤表單屬性的變化一般都采用事件監(jiān)聽(tīng)機(jī)制,跟蹤url
的變化也不落俗套。
對(duì)于hash
方式的前端路由,通??梢员O(jiān)聽(tīng) hashchange
事件,在事件回調(diào)中處理相應(yīng)的頁(yè)面視圖展示等邏輯。
此外,HTML5提供的 popstate
事件也會(huì)在url
的hash
發(fā)生改變時(shí)觸發(fā)。也就是說(shuō)如果可以忽略低版本瀏覽器,我們使用hash
方式路由時(shí)也可以采用監(jiān)聽(tīng)這個(gè)事件進(jìn)行回調(diào)處理。
那么,如果是采用history API的形式呢?根據(jù)MDN的描述:
調(diào)用
history.pushState()
或者history.replaceState()
不會(huì)觸發(fā)popstate
事件。popstate
事件只會(huì)在瀏覽器某些行為下觸發(fā), 比如點(diǎn)擊后退按鈕(或者在JavaScript中調(diào)用history.back()
方法)。
這也就是說(shuō),我們?cè)谑褂胔istory API改變?yōu)g覽器的url
時(shí),仍需要額外的步驟去觸發(fā) popstate
事件,例如調(diào)用 history.back()
會(huì) history.forward()
等方法。
從兼容性上來(lái)講,前面有提及hash
的方式兼容性更好。然而,對(duì)于低版本的瀏覽器,例如IE6等等,不支持 hashchange
事件。這個(gè)時(shí)候我們只能通過(guò) setInterval
設(shè)置心跳的方式去模擬 hashchange
。
var oldHash = location.hash;var oldURL = location.href; setInterval(function() { var newHash = location.hash; var newURL = location.href; if (newHash !== oldHash && typeof window.onhashchange === 'function') { // 執(zhí)行onhashchange回調(diào) window.onhashchange({ 'type': 'hashchange', 'oldURL': oldURL, 'newURL': newURL }); oldHash = newHash; oldURL = newURL; } }, 100);
這里,給出一個(gè)很簡(jiǎn)單的實(shí)現(xiàn):
router.js
function FrontRouter() { this.routes = {}; window.addEventListener('load', this.resolve.bind(this), false); window.addEventListener('hashchange', this.resolve.bind(this), false); } FrontRouter.prototype.route = function(path, callback) { this.routes[path] = callback || function() {}; }; FrontRouter.prototype.resolve = function() { this.curHash = location.hash.slice(1) || '/'; typeof this.routes[this.curHash] === 'function' && this.routes[this.curHash](); };
index.html
index.js
var router = new FrontRouter(); router.route('blue', function() { document.body.style.backgroundColor = 'blue'; }); router.route('yellow', function() { document.body.style.backgroundColor = 'yellow'; }); router.route('red', function() { document.body.style.backgroundColor = 'red'; });
前端路由大部分的應(yīng)用場(chǎng)景,就是我們現(xiàn)在熟知的單頁(yè)應(yīng)用SPA。
我們此前所描述的前端路由,建立在已經(jīng)打開(kāi)了一個(gè)初始頁(yè)面基礎(chǔ)之上,然后在這個(gè)頁(yè)面之內(nèi)進(jìn)行頁(yè)面替換。然而,我們?nèi)绾芜M(jìn)入這個(gè)初始頁(yè)面??jī)H靠前端路由肯定是力所不及。我們至少要向后端發(fā)送一次http請(qǐng)求,接收所需要加載的頁(yè)面不是嗎?
所以,我們并不能拋棄后端路由部分。這也意味著,我們需要和后端確認(rèn)各自的分工,哪些url歸前端解析,哪些歸后臺(tái)解析。
以上是“前端路由指的是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。