SPA需要在不刷新頁面的情況下做頁面更新的能力绰筛,這就需要引入前端路由枢泰,實(shí)際上,前端路由是利用了瀏覽器的hash或history屬性铝噩。
hash :
hash (url中#后面的部分)雖然出現(xiàn)在 URL 中衡蚂,但不會(huì)被包含在 http 請(qǐng)求中,對(duì)后端完全沒有影響骏庸,因此改變 hash 不會(huì)重新加載頁面毛甲。
當(dāng)hash改變時(shí),會(huì)觸發(fā)hashchange事件具被,監(jiān)聽該事件玻募,對(duì)頁面進(jìn)行更新。
? ? ? ? ? ? window.onhashchange = function() {
? ??????????????document.getElementById("demo").innerHTML = x;? ? //更新頁面內(nèi)容
? ? ? ? ? ? ? ? ......
????????????};
history :
history 利用了 html5 history interface 中新增的 pushState() 和 replaceState() 方法一姿。這兩個(gè)方法應(yīng)用于瀏覽器記錄棧七咧,
在當(dāng)前已有的 back跃惫、forward、go 基礎(chǔ)之上艾栋,它們提供了對(duì)歷史記錄 修改的功能(pushState將傳入url直接壓入歷史記錄棧爆存,replaceState將傳入url替換當(dāng)前歷史記錄棧)。
只是當(dāng)它們執(zhí)行修改時(shí)蝗砾,雖然改變了當(dāng)前的 URL 先较,但瀏覽器不會(huì)立即向后端發(fā)送請(qǐng)求。
? ??????????????pushState()悼粮、replaceState() 方法接收三個(gè)參數(shù):stateObj闲勺、title、url
? ? ? ? ? ? ? ? history.pushState({color: "red"}, "red", "red")矮锈;//設(shè)置狀態(tài)
? ??????????????window.onpopstate = function(event) {? //監(jiān)聽狀態(tài)
? ???????????????????if(event.state && event.state.color === "red") {
? ? ? ? ? ? ? ? ? ? ? ? ?document.body.style.color = "red";? ??//更新頁面內(nèi)容
? ? ? ? ? ? ? ? ? ? ? }
????????????????}
? ? ? ? ? ? ? ??// 改變狀態(tài)? *在使用history API改變?yōu)g覽器的url時(shí)霉翔,仍需要額外的步驟去觸發(fā)?popstate?事件,例如調(diào)用?history.back() 和 history.forward()?等方法
? ??????????????history.back();
? ??????????????history.forward();
history 對(duì)比? hash?
優(yōu)勢(shì):
pushState 設(shè)置的 url 可以是同源下的任意 url 苞笨;而 hash 只能修改 # 后面的部分债朵,因此只能設(shè)置當(dāng)前 url 同文檔的 url。
pushState 設(shè)置的新的 url 可以與當(dāng)前 url 一樣瀑凝,這樣也會(huì)把記錄添加到棧中序芦;hash 設(shè)置的新值不能與原來的一樣,一樣的值不會(huì)觸發(fā)動(dòng)作將記錄添加到棧中粤咪。
pushState 通過 stateObject 參數(shù)可以將任何數(shù)據(jù)類型添加到記錄中谚中;hash 只能添加短字符串。
pushState 可以設(shè)置額外的 title 屬性供后續(xù)使用寥枝。
劣勢(shì):
history 在刷新頁面時(shí)宪塔,如果服務(wù)器中沒有相應(yīng)的響應(yīng)或資源,就會(huì)出現(xiàn)404囊拜。因此某筐,如果 URL 匹配不到任何靜態(tài)資源,則應(yīng)該返回同一個(gè) index.html 頁面冠跷,這個(gè)頁面就是你 app 依賴的頁面南誊。
hash 模式下,僅 # 之前的內(nèi)容包含在 http 請(qǐng)求中蜜托,對(duì)后端來說抄囚,即使沒有對(duì)路由做到全面覆蓋,也不會(huì)報(bào) 404橄务。