一、hash模式
hash是指url上#和其后面的鏈接,#稱之為錨點(diǎn)。
由于 hash 值變化不會(huì)導(dǎo)致瀏覽器向服務(wù)器發(fā)出請(qǐng)求,而且 hash 改變會(huì)觸發(fā) hashchange 事件(hashchange只能改變 # 后面的url片段);更關(guān)鍵的一點(diǎn)是,因?yàn)閔ash發(fā)生變化的url都會(huì)被瀏覽器記錄下來(lái),從而你會(huì)發(fā)現(xiàn)瀏覽器的前進(jìn)后退都可以用了。
window.location.hash = 'qq' // 設(shè)置 url 的 hash,會(huì)在當(dāng)前url后加上 '#qq'
var hash = window.location.hash // '#qq'
window.addEventListener('hashchange', function(){
// 監(jiān)聽(tīng)hash變化,點(diǎn)擊瀏覽器的前進(jìn)后退會(huì)觸發(fā)
})
二、history模式
首先,hash 本來(lái)是拿來(lái)做頁(yè)面定位的,如果拿來(lái)做路由的話,原來(lái)的錨點(diǎn)功能就不能用了。其次,hash 的傳參是基于 url 的,如果要傳遞復(fù)雜的數(shù)據(jù),會(huì)有體積的限制,而 history 模式不僅可以在url里放參數(shù),還可以將數(shù)據(jù)存放在一個(gè)特定的對(duì)象中。
history api可以分為兩大部分:切換和修改
1、切換歷史狀態(tài)包括back、forward、go
這三個(gè)方法,對(duì)應(yīng)瀏覽器的前進(jìn),后退,跳轉(zhuǎn)操作;(跳轉(zhuǎn)操作:在前進(jìn)后退上長(zhǎng)按鼠標(biāo),會(huì)出來(lái)所有當(dāng)前窗口的歷史記錄,從而可以跳轉(zhuǎn))
history.go(-2);//后退兩次
history.go(2);//前進(jìn)兩次
history.back(); //后退
hsitory.forward(); //前進(jìn)
2、修改歷史狀態(tài)包括了 pushState, replaceState兩個(gè)方法
這兩個(gè)方法接收三個(gè)參數(shù):stateObj, title, url
window.history.pushState(state, title, url)
// state:需要保存的數(shù)據(jù),這個(gè)數(shù)據(jù)在觸發(fā)popstate事件時(shí),可以在event.state里獲取
// title:標(biāo)題,基本沒(méi)用,一般傳 null
// url:設(shè)定新的歷史記錄的 url。新的 url 與當(dāng)前 url 的 origin 必須是一樣的,否則會(huì)拋出錯(cuò)誤。url可以是絕對(duì)路徑,也可以是相對(duì)路徑。
//如 當(dāng)前url是 https://www.baidu.com/a/,執(zhí)行history.pushState(null, null, './qq/'),則變成 https://www.baidu.com/a/qq/,
//執(zhí)行history.pushState(null, null, '/qq/'),則變成 https://www.baidu.com/qq/
window.history.replaceState(state, title, url)
// 與 pushState 基本相同,但她是修改當(dāng)前歷史記錄,而 pushState 是創(chuàng)建新的歷史記錄
window.addEventListener("popstate", function() {
// 監(jiān)聽(tīng)瀏覽器前進(jìn)后退事件,pushState 與 replaceState 方法不會(huì)觸發(fā)
});
history模式下,不怕前進(jìn)后退,就怕h5刷新頁(yè)面,因?yàn)樗⑿马?yè)面是向服務(wù)器請(qǐng)求了。
history 模式改變 url 的方式會(huì)導(dǎo)致瀏覽器向服務(wù)器發(fā)送請(qǐng)求,這不是我們想看到的,我們需要在服務(wù)器端做處理:如果匹配不到任何靜態(tài)資源,則應(yīng)該始終返回同一個(gè) html 頁(yè)面。
nginx服務(wù)器配置:
// 意思為,匹配url和url/下的文件,如果嗎,沒(méi)有匹配到,則返回index.html
location / {
try_files $uri $uri/ /index.html;
}