HTML5裏引用了新的API,history.pushState和history.replaceState,就是經過這個接口作到無刷新改變頁面URL的。javascript
傳統的ajax有以下的問題:java
一、能夠無刷新改變頁面內容,但沒法改變頁面URLjquery
二、爲了更好的可訪問性,內容發生改變後,一般改變URL的hashajax
三、hash的方式不能很好的處理瀏覽器的前進、後退等問題後端
四、進而瀏覽器引入了onhashchange的接口,不支持的瀏覽器只能定時去判斷hash是否改變跨域
五、但這種方式對搜索引擎很不友好瀏覽器
六、twitter和google約定了使用#!xxx(即hash第一個字符爲!),搜索引擎進行支持。搜索引擎
爲了解決傳統ajax帶來的問題,HTML5裏引入了新的API,即:history.pushState, history.replaceStategoogle
能夠經過pushState和replaceState接口操做瀏覽器歷史,而且改變當前頁面的URL。url
pushState是將指定的URL添加到瀏覽器歷史裏,replaceState是將指定的URL替換當前的URL。
var state = { title: title, url: options.url, otherkey: othervalue }; window.history.pushState(state, document.title, url);
state對象除了要title和url以外,你也能夠添加其餘的數據,好比:還想將一些發送ajax的配置給保存起來。
replaceState和pushState是類似的,這裏就很少介紹了。
window對象上提供了onpopstate事件,上面傳遞的state對象會成爲event的子對象,這樣就能夠拿到存儲的title和URL了。
window.addEventListener('popstate', function(e){ if (history.state){ var state = e.state; //do something(state.url, state.title); } }, false);
這樣就能夠結合ajax和pushState完美的進行無刷新瀏覽了。
一、傳遞的URL必須是同域下的,沒法跨域
二、state對象雖然能夠存儲不少自定義的屬性,但對於不可序列化的對象則不能存儲,如:DOM對象。
這種模式下除了當前使用ajax能夠無刷新瀏覽外,還要保證直接請求改變的URL後也能夠正常瀏覽,因此後端要對這些處理下。
一、對使用pushState的ajax發送一個特殊的頭,如: setRequestHeader('PJAX', 'true')。
二、後端獲取到有PJAX=true的header時,將頁面中通用的部分都不輸出。好比:PHP能夠經過下面的判斷
function is_pjax(){ return array_key_exists('HTTP_X_PJAX', $_SERVER) && $_SERVER['HTTP_X_PJAX'] === 'true'; }
雖然接口上只有pushState、replaceState、onpopstate,但在使用的時候須要作不少的處理。
針對這個已經寫好了一個基於jquery的插件,接下來的文章會詳細介紹如何使用pjax(ajax+pushState)進行無刷新改變URL瀏覽。