2011年3月12日 星期六

瀏覽器切換上下頁的行為以及 AJAX

記錄一下觀察到的東西, 可能有錯。

瀏覽器在切換 URL 時會存下對應的檔案 (HTML、CSS、etc), 在瀏覽器按上下頁時, 瀏覽器會重新 render 該頁, 不會重送 HTTP request 取得內容。這表示:
  • 會重新執行 javascript code 
  • 會另外觸發一些特定的 javascript event  (有改變 URL)
對 AJAX 來說, 這造成一個問題, 因為 AJAX 沒有改變 URL, 自然無法直覺地切換上下頁。但有個還不錯的偷吃步作法, 利用瀏覽器處理 URL 中「#」的行為做出切換頁面的效果。在 URL 中有「#」的情況下, 瀏覽器會記錄更改的 URL, 並且不會送出 HTTP request, 所以可以按上下頁切換。比較特別的是, 瀏覽器不會重新 render 該頁, 因為「#」原本的用意是跳到同一頁面內的不同位置, 重新 render 會拖慢速度。於是有人利用這點, 配合改變 URL 觸發的 javascript event, 包了函式庫, 用來管理 AJAX 切換頁面的效果。

以 jQuery Address 為例, 概念很簡單: 將 AJAX 的參數記在「#」後面, 註冊所有會換頁的事件, 在送出 AJAX 前先改變 URL, 改變「#」後的內容, 這樣會觸發事件, 接著再統一在改變 URL 觸發的事件內從「#」後取回參數, 看要做什麼事。由於改變「#」後的內容, 瀏覽器不會送 HTTP request, 不用擔心為了記錄 URL 而多送 HTTP request。看看範例程式碼和玩玩範例, 會比較快理解它的行為。

看起來相當完美, 唯一的小缺憾是, 切換上下頁時會觸發 URL 改變的事件, javascript 的對應行為就是執行我們原本寫的 handler, 於是會重送出 HTTP request (AJAX), 這違反我們原本對切換上下頁的認知, 它不該多送 HTTP request。若要克服這個缺點, 就得用 javascript 實作 cache 機制, 先查看看是否已取得這組參數對應的內容, 是否沒有過期的顧慮, 沒有的話就不用送 HTTP request。我想一般來說不會寫到那麼麻煩, 若回上頁要重送 HTTP request, 就讓它重送吧, 程式會比較好維護。

備註

2012-03-06 更新

javascript - Updating address bar with new URL without hash or reloading the page 提到 HTML5 的新 api: window.history.pushState(), 在 jQuery Address 裡也有用到它。若想自己另外實作這個功能不想套 library 的架構, 可考慮直接用它, 現今支援 HTML5 的瀏覽器又更多了。

沒有留言:

張貼留言

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...