使用ajax和history.pushState無刷新改變頁面URL

HTML5裏引用了新的API,history.pushState和history.replaceState,就是經過這個接口作到無刷新改變頁面URL的。javascript

與傳統的AJAX的區別

傳統的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瀏覽。

相關文章
相關標籤/搜索