
PJAX 深入淺出
HTML5 History API
在講 pushState 之前,先來回顧一下 HTML History 的歷史操作功能
History
上一頁
history.back()
history.go(-1)
下一頁
history.forward()
history.go(1)
查看歷史瀏覽總數
window.history.length
HTML5 新增
history.pushState()
history.replaceState()
What is pushState ?
- pushState = history.pushState
- 它和 location.hash 相似
- 用來操作歷史瀏覽紀錄
- HTML5 在 history 事件新加入
history.pushState()
history.replaceState()
支援度
使用 history.pushState()後,會改變 XMLHttpRequest 時 HTTP 標頭中 referrer 的值。
referrer 會是創造 XMLHttpRequest 物件時的當前視窗文件(this)的 URL。
這樣可能不太瞭解什麼意思
來個範例看看
DEMO1
先連到此網址 http://mozilla.org/foo.html
打開 Chrome Develop Tools
輸入以下程式碼
history.pushState({ foo: "bar" }, "test", "bar.html");可以看到網址列已經變成 https://www.mozilla.org/zh-TW/bar.html
此時隨便連到別的網站如 https://www.google.com.tw
再按上一頁
可以看到網址仍然是 https://www.mozilla.org/zh-TW/bar.html
但內容仍然跟原本的 http://mozilla.org/foo.html 一模一樣
但是我們沒有對連結特別去做處理
重整之後抓不到 bar.html 這個連結的資料
照理說應該會導到 404 頁面
但由於我們測試的頁面本來就是 404 頁面,所以看起來以為沒變其實它已經失去連結了
這就是 pushState 有趣的地方
DEMO2
先連到此網址 http://example.com/example.html
打開 Chrome Develop Tools
輸入以下程式碼
window.onpopstate = function(e) {
alert(JSON.stringify(e.state));
};history.pushState({page: 1}, “title 1”, “?page=1”);
history.pushState({page: 2}, “title 2”, “?page=2”);
history.replaceState({page: 3}, “title 3”, “?page=3”);我們給予一個 onpopstate 事件在我們換頁的時候能 alert 出 history.state 現在的值以讓我們驗證我們現在的狀態
接下來照順序一行一行輸入
history.back(); // alert {page: 1}
history.back(); // alert null
history.go(2); // alert {page: 3}結果跟想像中的不太一樣
第二次的 history.back() 為什麼沒有跳出 {page: 2} 的結果?
可以往上看 DEMO2 的那張圖
得知 replaceState 會蓋掉上一次的 state 狀態
於是乎 {page: 2} 的狀態被蓋掉
只剩下 {page: 3} 且上一頁的狀態為 {page: 1}
AJAX With SEO
我們都知道,AJAX 動態資料很難被搜尋引擎搜尋到,必須經過重重的關卡與處理才能有一個好的 SEO 條件
GOOGLE 做了一個方式,在網址列後方加上 #!
http://example.com#!1
搜尋引擎會由 GOOGLE 轉譯成
http://example.com/?_escaped_fragment_=1
Twiter
Twitter 曾經實行此計畫
將網址 http://twitter.com/ruanyf
改成 http://twitter.com/#!/ruanyf
但由於網址實在又臭又長,實行了大約半年就被使用者罵爆
於是就又改成其它方式了
Google建議 AJAX 使用 PushState而非 hashbang
Matt Cutts說Google對於兩者的AJAX方式都「能夠」處理,但是如果你使用PushState,對於抓取而言不需要特別處理,因此我們鼓勵使用PushState。
如我們之前所說的,不要太相信Google「能夠」處理各種Javascript,因為「能夠」處理與「願意」處理是兩回事。
因為Google需要處理太多事情,並且每處理一件事情都會耗費很多資源,例如電力、CPU、記憶體、儲存空間、時間 … 等等。因此如果你只是小咖的網站,但是使用很繁複的Javascript,Google可能花了很大力氣去抓取出來,但是最後發現只是一堆沒有人想看的垃圾,因此如果你不是天王級的網站,千萬不要相信Google「能夠」處理各種Javascript,你必須讓網站非常容易抓取。
