wml

          轉:Java 開發員AJAX 常見問題

          Java 開發員AJAX 常見問題

          作者: Greg Murray? 譯者:Cheng Fang

          原文:https://blueprints.dev.java.net/ajax-faq.html

          現在我們都有機會用AJAX 了,好多人發現這是個全新的世界。許多開發員會通過現有的框架來接觸到AJAX ,或許你想深入鉆研,擴充現有的功能。這些常見問題就是針對想在應用內加上AJAX 功能的開發員的。

          1. 我應該考慮用 AJAX嗎?
          2. AJAX 能不能和Java一起用?
          3. 難道我的框架不提供AJAX嗎?
          4. 該從哪里開始?
          5. 創建我自己的AJAX功能,我要知道些什么?
          6. 我真的需要學JavaScript嗎?
          7. 有哪些 JavaScript 庫和框架可以幫助Java開發員?
          8. 我應該使用哪種返回值類型, XML 或 text, JavaScript, 或 HTML?
          9. AJAX 用起來方便不方便?
          10. 我該怎樣調試 JavaScript?
          11. 在AJAX調用中,我應該用HTTP GET還是 POST?
          12. 我該怎樣提供國際化的AJAX交互?
          13. 我該如何處理并發的AJAX 請求?
          14. 在服務器端怎樣和AJAX客戶端交流?
          15. 針對 AJAX 客戶,在哪里儲存狀態?
          16. 怎樣提交表單或表單的一部分,但不刷新頁面?
          17. 服務器端和客戶端,誰有控制權?
          18. AJAX 在安全性方面有沒有問題?
          19. 我什么時候用同步請求而不用異步請求?
          20. 那些 applet和plugin該怎么辦?
          21. 該怎樣處理向前和向后按鈕?
          22. 用AJAX 怎樣發送圖像?
          23. 該怎樣創建一個線程來實現AJAX輪詢(polling)?

          我應該考慮用 AJAX嗎?

          AJAX現在當然很紅,但它不一定適合你。AJAX只能用在最新的瀏覽器上,暴露出許多瀏覽器兼容性問題,對許多人它還要求學會一些新技術。Alex Bosworth 寫了篇不錯的網志 AJAX Mistakes,在你全力投入AJAX以前值得一看。

          另一方面,你可以實現豐富的,高度交互性的,快速響應的WEB應用,它們看起來真的很快。盡管人們還在爭論基于AJAX的應用是不是真的更快, 用戶已感到更直接了,因為當數據在后臺交換的時候,用戶就收到了積極反饋。如果你較早采用了AJAX,能夠處理瀏覽器兼容性問題,而且愿意學習一些新技術,那么AJAX是適合你的。謹慎起見,你可以試著把應用的一小部分或者小組件轉化成AJAX。我們都喜歡新技術,但要記住AJAX的目的是要改善而不是妨礙用戶的體驗。

          AJAX 能不能和Java一起用?

          當然。Java很適合AJAX!你可以用Java企業版服務器來生成AJAX 客戶端頁面并處理進來的請求,為AJAX 客戶端管理服務器端的狀態,并且把AJAX 客戶端聯接到企業資源。JavaServer Faces 組件模型非常適合于定義和使用AJAX組件。

          難道我的框架不提供AJAX嗎?

          你可能已經受益于AJAX。許多現有的基于Java 的框架已經有一定的AJAX 交互,許多新的框架和組件正在被開發來更好地支持AJAX。這里我不想列出所有用AJAX 的Java框架,因為我怕會遺漏一些。但是你可以在這里找到一個不錯的列單: www.ajaxpatterns.org/Java_Ajax_Frameworks.

          如果你還沒有選好一個框架,我建議你考慮使用JavaServer Faces 或者基于JavaServer Faces的框架。你可以用JavaServer Faces組件來抽象化處理許多細節:生成JavaScript, AJAX交互, 和DHTML處理,這樣JSF開發員就可以更方便地使用AJAX,它們還可以作為插件裝入支持JSF的IDE內,比如 Sun Java Studio Creator.

          該從哪里開始?

          如果你現在的框架不能滿足你的用例,你想開發自己的AJAX組件和功能,我建議你先看一下這篇文章Asynchronous JavaScript Technology and XML (AJAX) With Java 2 Platform, Enterprise Edition。(譯者注:中文版 在Java2平臺企業版中應用異步 JavaScript技術和XML(AJAX)

          如果你想看一個很基本的例子和源代碼,這里有 Using AJAX with Java TechnologyBlueprints AJAX Home 有更完整的AJAX資源。

          接下來,我建議你花些時間研究AJAX庫和框架。如果你想自己寫AJAX客戶端腳本,最好不要再重復勞動了。

          Dave Crane,Eric Pascarello和Darren James的AJAX in Action也不錯。這本書有附錄中講學習 JavaScript,對Java開發員有幫助。

          創建我自己的AJAX 功能,我要知道些什么?

          如果你不想利用已有的AJAX組件,這里是一些需要注意的地方。

          準備學習動態HTML (DHTML), AJAX的基礎技術。DHTML讓用戶與網頁間通過瀏覽器現時交互成為可能。DHTML結合了JavaScript,文檔對象模型(DOM)和層疊樣式表 (CSS).

          • JavaScript - JavaScript是個寬松類型的,基于對象的腳本語言。它是AJAX交互的關鍵,而且所有的主流瀏覽器都支持它。當頁面中的一個事件發生時,例如,載入頁面,鼠標點擊,或表單元素上的按鍵,JavaScript就被調用了。
          • 文檔對象模型(DOM) - 用來讀取和更改結構化文檔的應用編程接口。在大多數情況下DOM代表XML和HTML文檔的結構。
          • 層疊樣式表(CSS) - 讓你定義頁面的外觀,例如:字體,顏色,大小,和定位。CSS讓你清晰地分隔開內容和形式,并且可以用JavaScript來編程改變。

          理解HTTP的請求/回應這一基本性質也很重要。如果你在配置XMLHttpRequest時忽略了GET和POST方法的區別,或者在處理回調時忽略了HTTP狀態代碼,你會碰到許多難題。

          從某種意義上說,JavaScript是一種客戶端的膠合體。JavaScript被用來創建XMLHttpRequest對象并觸發異步調用。 JavaScript被用來解析返回的內容。JavaScript被用來分析返回的數據并處理返回的信息。用JavaScript可以通過DOM API往HTML里注入內容和改變CSS。

          我真的需要學JavaScript嗎?

          一般來說,是的,如果你想為你的WEB應用開發新的AJAX功能。

          另外一方面, JSF 組件和組件庫能抽象化JavaScript,DOM和CSS的細節。這些組件能生成必要的工件(artifacts)來支持AJAX交互。可視的工具,象Java Studio Creator,也可以利用支持AJAX的JSF組件來創建應用,應用開發者就不用擔心AJAX的許多細節了。如果你打算寫自己的 JSF組件,或者想把組件間的事件串聯在一起,你應該對JavaScript有個基本了解。你可以從你頁面里的JavaScript調用一些客戶端的JavaScript 庫(在下面談到)來抽象化測聲器間的差異。 Object Hierarchy and Inheritance in JavaScript 是一個供Java開發員學習JavaScript對象的很好的參考。

          有哪些JavaScript 庫和框架可以幫助Java開發員?

          已經有許多庫和框架(而且許多還在涌現出來)能幫助我們抽象化這些討厭的瀏覽器差異。三個不錯的庫是:The Dojo Toolkit, Prototype, and DWR.
          • The Dojo Toolkit 包含一些API和工具來支持開發富WEB應用。Dojo包含一個智能的包裝系統,用戶界面效果,拖放方法(Drag and Drop) API,小應用(widget)API,事件抽象,客戶存儲API,以及AJAX交互API。Dojo解決了一些常見的可用性(Usability)問題, 比如,處理瀏覽器導航問題包括察覺瀏覽器退后按鈕,更改地址欄里的URL來收藏書簽,當客戶端不完全支持AJAX和JavaScript時妥善處理。Dojo就好比是JavaScript庫中的一把瑞士軍刀。 它在一個庫里提供了最廣泛的選擇,而且能很好地支持新老瀏覽器。
          • Prototype 專注于通過JavaScript AJAX對象進行AJAX 交互,它包含了若干對象來做基本的工作,比如發出請求,更新部分文檔,往文檔里插入內容,以及定期更新部分文檔。Prototype JavaScript庫包含了一套JavaScript對象來代表AJAX請求,和一些效用函數來讀取頁面內的數據和修改DOM。 Script.aculo.usRico就是建立在Prototype之上并提供了用戶界面效果,支持拖放效果,以及一些圍繞JavaScript的不工具(widgets)。如果你想支持AJAX交互和一些基本的功能,Prototype是個很好的選擇。如果你需要用戶界面效果,Script.aculo.us和Rico是不錯的。

          • Yahoo UI Library 是一個通過API來支持富客戶端的效用庫和一套小應用。這個效用庫包括了支持跨瀏覽器的AJAX交互,動畫,DOM腳本,拖放,以及跨瀏覽器事件。 Yahoo UI Library提供較好的文檔和許多例子。

          • DWR (Dynamic Web Remoting) 是一個客戶端和服務器端的框架,它專注于允許開發員實現從客戶端JavaScript到J2EE WEB容器內的普通Java對象(Plain Old Java Object)之間的遠程調用。在服務器端,DWR用一個Servlet來和Java對象交互,并返回Java對象或做成了對象的XML文檔。 DWR安裝使用方便,和其它Java技術配合較好。如果你想要一個整合性能良好,同時支持客戶端和服務器的框架,那就用 DWR.

          • Zimbra 是個客戶端和服務器的框架,它專注于支持消息(messaging),包括向使用JavaScript的客戶端提供電子郵件服務。在它的工具包中有抽象化瀏覽器差異的UI API(同時也包括了許多內在的小應用),支持UI事件通信和客戶與服務器之間通信的API,簡化客戶端JavaScript開發的效用類,抽象化了的 DOM API以簡化跨瀏覽器操作,和一套網絡API來幫助JavaScript客戶端AJAX和SOAP通信。

          有好多新的JavaScript庫正在涌現出來,以上只是回顧了比較常見的庫。選擇最適合你需要的。盡管你最好用一個框架,當然也可以同時用多個。更詳細的客戶端框架列單,請看:Survey of AJAX/JavaScript Libraries.

          我應該使用哪種返回值類型, XML 或 text, JavaScript, 或 HTML?

          這要看情況。很清楚,AJAX里的X代表了XML,但是一些AJAX支持者馬上也指出,AJAX本身并不排除使用其它種類做載荷(PAYLOAD),比如,JavaScript, HTML, 或是純文本格式。

          • XML - Web Services和AJAX看起來天生般配。你可以用客戶端的API來下載和解析來自REST一類Web Services的XML內容。(不過,要小心在有些基于SOAP的Web Services中載荷會變得又大又復雜,所以不適合AJAX技術)。
          • 純文本格式 - 在種情況下,服務器產生的文本被注入文檔中,或用客戶端邏輯來評估。
          • JavaScript - 是純文本格式的延伸,不過服務器端組件會傳遞JavaScript腳本的分段,包括JavaScript對象聲明。你可以在客戶端用JavaScript eval()函數來創建這些對象。JSON,一個基于 JavaScript對象的數據交換規范,就是依賴了這種技術。
          • HTML - 直接把服務器生成的HTML分段注入文檔,這通常是一種很有效的AJAX方法。不過,要讓服務器端的組件和客戶端的顯示內容保持一致會有點復雜。

          網絡聚合(Mashup) 這是一個時下流行的術語,它從離散的WEB SERVICES和其它在線API獲取內容,結合在一起創建全新的WEB應用。 一個很好的網絡聚合的例子就是housingmaps.com,它把craiglist.org 的住房廣告和 maps.google.com的地圖結合在一起。

          AJAX用起來方便不方便?

          通過AJAX交互和DHTML的途徑來獲取數據,動態更新頁面,這在本質上是會大幅度地改變頁面的外觀和狀態。用戶可能會在任何時候用到瀏覽器的向前或退后按鈕,書簽收藏當前頁面,從地址欄復制URL后通過電子郵件或聊天發給朋友,或者是打印頁面。在設計AJAX應用時,你應該考慮在發生這些情況時你預期的結果是怎樣:導航,書簽收藏,打印,瀏覽器支持, 如下所述:

          • 導航- 向前,退后,刷新和書簽收藏這些瀏覽器按鈕被點擊時,你應用設計預期的結果是什么?你雖然可以用手工地實現一些歷史控制,但更簡便的方法是用一些能提供歷史和導航控制API的JavaScript框架,比如Dojo
          • 書簽收藏和URL分享 - 許多用戶想書簽收藏或從地址欄里拷貝URL。Dojo 支持客戶端書簽收藏和修改URL。
          • 打印- 有些時候打印動態產生的頁面會有問題。

          開發員使用AJAX時其它考慮因素:

          • 瀏覽器支持 - 并不是所有的瀏覽器,或一個瀏覽器的所有版本都支持所有的AJAX或DHTML功能。quirksmode.org 列舉了瀏覽器支持情況和可能的變通方法。
          • JavaScript被關閉 - 你還應該考慮如果用戶關閉使用JavaScript,你該怎么辦。另外,有些用戶的瀏覽器上因為有些原因不能支持JavaScript和CSS。
          • 等待時間(Latency) - 在你的設計中應該考慮到等待時間。應用在運行時應該比部署時更加響應迅速。同時要考慮到發出多個請求時,返回的次序是沒有保障的。詳情請看AJAX Latency problems: myth or reality?
          • 可訪問性 - 確保你的網站能讓有殘障的人訪問,這不光是一個高尚的目標,在很多地區也是法律。有許多優秀的支撐技術能幫助他們使用網絡,盡管他們有視覺,聽覺,體力,語言,認知和神經方面的殘障。有一點前瞻性,理解這方面的豐富文檔和最好實踐,你就能確保你的應用符合這些支撐技術的要求。

          降解效果(Degradability)這個術語描述了WEB應用用于適應廣泛的瀏覽器功能的一系列技巧。許多AJAX庫有內置的自動降解方式。如果你要寫自己的AJAX功能,考慮采納一些標準組織,比如World Wide Web Conrsoritum (W3C), 和草根運動,比如Web Standards和其它人的最佳實踐。這樣你的應用在不支持AJAX的瀏覽器上仍然能運行,雖然它失去了一些很搶眼的效果。

          記住不要只是為了顯得酷而用AJAX。你打造WEB應用是為了給人用的。如果和他們的瀏覽器上不兼容,用戶就不會用你的應用。

          我該怎樣調試 JavaScript?

          沒有很多調試器能同時支持客戶端和服務器端調試。我肯定隨著AJAX的普及,這種情況會改變。我現在分開調試客戶端和服務器。以下是一些關于常見瀏覽器上的客戶端調試器的情況:

          • Firefox/Mozilla/Netscape - 在一個內置的調試器Venkman很有幫助。我喜歡先在 Firefox開發應用,然后再到其它瀏覽器上去試。
          • Safari - 有一個調試器,你需要先開戶。詳情請看Safari FAQ
          • Internet Explorer - MSDN Documentation上有關于調試JavaScript的文檔。Internet Explorer developer toolbar可能也有幫助。

          除了調試器能幫忙,還有一種常用的方法叫“對話框調試(Alert Debugging)”。在這種情況下你加入"alert()"函數調用,就好比在JAVA中用System.out.println一樣。盡管是一個很小的竅門,對大部分情況都管用。有些框架,象Dojo,提供 API來追蹤調試語句。

          在AJAX調用中,我應該用HTTP GET還是 POST?

          如果相對于一個待定的URL的數據一會改變,那么AJAX請求應該用HTTP GET方法。如果服務器會更新狀態,那么就應該用HTTP POST方法。這和HTTP idempotency recommendations的要求是一致的,也是大家為創造一個統一的WEB應用設計而高度推薦的做法。

          我該怎樣提供國際化的AJAX交互?

          不能認為用了XML, 你就能以AJAX請求發送和獲取區域化的內容。要提供國際化的AJAX組件,你需要做以下這些要求:

          • 把頁面字符集設成目標語言支持的編碼。你趨向于使用UTF-8,因為它涵蓋了在部分語言。以下一個HTML/JSP頁面的meta聲明設置了 content type:
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
          • 在頁面內JavaScript確保每個發往服務器的參數都被編碼。JavaScript提供了一個escape()函數來返回統一碼(UNICODE)轉義字符串,這樣區域化的文本就以十六進制的格式出現。更多關于JavaScript編碼的信息,請看Comparing escape(), encodeURI(), and encodeURIComponent().
          • 服務器端組件用HttpServletRequest.setCharacterEncoding()方法設置字符編碼。這必須發生在用 HttpServletRequest.getParameter()方法讀取區域化參數以前。如果是UTF-8,那就應該是 request.setCharactherEncoding("UTF-8");.

          返回AJAX回應的服務器端組件需要把回應的編碼設成和該頁面一樣的編碼。

              response.setContentType("text/xml;charset=;UTF-8");
          response.getWriter().write("<response>invalid</response>");

          關于在Java企業版上使用AJAX,更多資料請看AJAX and Internationalization,開發多種語言應用,請看Developing Multilingual Web Applications Using JavaServer Pages Technology.

          我該如何處理并發的AJAX 請求?

          通過JavaScript你可以同時處理多個AJAX 請求。為了確保妥善的后處理,我建議使用JavaScript閉包(JavaScript Closures)。下面這個例子顯示了一個XMLHttpRequest 被抽象化為JavaScript對象AJAXInteraction。傳進的參數是要調用的URL和處理結束后要調用的函數。

          function AJAXInteraction(url, callback) {

          var req = init();
          req.onreadystatechange = processRequest;

          function init() {
          if (window.XMLHttpRequest) {
          return new XMLHttpRequest();
          } else if (window.ActiveXObject) {
          return new ActiveXObject("Microsoft.XMLHTTP");
          }
          }

          function processRequest () {
          if (req.readyState == 4) {
          if (req.status == 200) {
          if (callback) callback(req.responseXML);
          }
          }
          }

          this.doGet = function() {
          req.open("GET", url, true);
          req.send(null);
          }

          this.doPost = function(body) {
          req.open("POST", url, true);
          req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
          req.send(body);
          }
          }

          function makeRequest() {
          var ai = new AJAXInteraction("processme", function() { alert("Doing Post Process");});
          ai.doGet();
          }

          在上例中,makeRequest()函數創建了一個AJAXInteraction,傳入兩個參數:要調用的URL“processme”和一個內聯函數。這個內聯函數會彈出對話框來顯示信息"Doing Post Process"。調用ai.doGet()就啟動了AJAX 互動,當映射到URL "processme" 的服務器端組件返回一個文檔,這個文檔再被傳給創建這個AJAXInteraction時指定的回調函數。

          使用這樣的閉包能確保對應于一特定的AJAX交互的回調函數能被正確調用。當你使用多個閉包對象來做XmlHttpRequests時仍需小心,因為在任何一特定時刻都只有有限的套接字(SOCKET)用來發出請求。因為只能有有限數目的并行請求,Internet Explorer只允許任何時刻最多兩個并行AJAX請求 。其它瀏覽器可能會允許更多,但一般是三個到五個之間。你也可以用來管理AJAXInteraction對象。

          有一點要注意,當從客戶端發出多個AJAX請求時,它們的返回值沒有特定的次序。在回調函數中使用閉包能確保這些信賴能被正確處理。

          這個討論很有幫助Ajaxian Fire and Forget Pattern

          在服務器端怎樣和AJAX客戶端交流?


          對于返回值類型XML,"Content-Type" 要設成"text/xml"。在SERVLET里可以用 HttpServletReqponse.setContentType()。許多XMLHttpRequest 實現如果發現"Content-Type"已經設了會報錯。一面的代碼顯示了如何設"Content-Type":

              response.setContentType("text/xml");
          response.getWriter().write("<response>invalid</response>");

          你可能要考慮是不是要設緩存標頭。在些時候,比如自動補全,你可能要通知代理服務器和瀏覽器不要緩存結果。

              response.setContentType("text/xml");
          response.setHeader("Cache-Control", "no-cache");
          response.getWriter().write("<response>invalid</response>");
          開發員注意:如果這個標頭沒有設,Internet Explorer 對于HTTP GET方法的響應會自動用緩存的結果。這可能會引起一些問題。所以在開發的時候你可能要設這個標頭。

          針對AJAX客戶,在哪里儲存狀態?

          和任何基于瀏覽器的WEB應用一樣,你有以下這些選擇:

          • 在客戶端使用cookie - 大小有限(一般是每個域名20個cookie ,每個cookie 4KB,總共80KB)。除非加密,否則不安全。加密是困難的,但用JavaScript也不是不可能。
          • 在客戶端頁面中 - 這種方法安全,但用起來困難,容易出問題。我的一篇網志有更詳細的討論:Storing State on the Client
          • 在客戶端文件系統內 - 如果瀏覽器已有權限寫往本地文件系統,這是可行的。取決于你的用例,這可能也就夠了,但也需謹慎。
          • 在服務器端 - 這和傳統模式最想象:客戶的狀態保存在服務器上。如何保持數據一致會是個問題,所以我們針對這設計了這樣一種方案Refreshing Data。當我們把更多的數據處理移往客戶端時,就需要重新評估在哪里儲存狀態。

          怎樣提交表單或表單的一部分,但不刷新頁面?

          當建立表單的時候,要確保"form"元素的"onSubmit"屬性設成一個返回false的JavaScript函數。

            <form onSubmit="doAJAXSubmit();return false;" >
          <input type="text" id="tf1" />
          <input type="submit" id="submit1" value="Update"/>
          </>

          用同樣的方法,你也可以聯接函數和表單按鈕,從而來提交表單:

            <form onSubmit="doAJAXSubmit();return false;" >
          <input type="text" id="tf1" />
          <input type="button" id="button1" onClick="doAJAXSubmit()" value="Update"/>
          </>

          注意:表單上的"onSubmit"屬性已被設置。如果用戶在文本輸入框中按了回車,表單也會被提交。所以你要處理這種情況。

          當更新頁面時,我建議你等到確保AJAX已經順利更新了表單數據后再更新頁面數據。否則,數據可能沒有適當更新,用戶卻不知道。我喜歡在做部分更新時給用戶一個提醒信息,等AJAX交互順利結束后,再更新頁面。

          服務器端和客戶端,誰有控制權?

          這要看情況而定。對于AJAX來說,答案在兩者中間。服務器端組件可實施更強的中央控制,或者服務器端和客戶端一起來控制。

          • 中央化的服務器端控制器 - 當你用一個更中央化的控制器時,關鍵是要確保客戶端頁面的數據和服務器端保持一致。有些應用在服務器保持狀態,并把所有的更新通過一個簡單的 JavaScript控制器推送到客戶端的DOM。
          • 客戶端和服務器端的控制器 - 這種設計會用JavaScript來做所有與表現有關的控制,事件處理,頁面修改,并在客戶端渲染顯示業務數據。服務器端負責的事情包括業務邏輯,和把更新后的業務數據推送給客戶。在這種情況下,服務器除了發送往客戶的最初頁面以外,并不熟悉表現層的情況,

          在有些用例中,整個AJAX應用只有一個頁面。但要記住,如果你選用了這種設計,務必考慮到瀏覽器導航和書簽收藏。

          取決于你想實現什么,這兩種方法都可以采用。我趨向于讓把控制分布到服務器端和客戶端。

          AJAX在安全性方面有沒有問題?

          用戶通過查看頁面源代碼就可以看見JavaScript的源代碼。沒有用戶賦予的權限,JavaScript不能訪問本地文件系統。AJAX只能與提供該頁面下載的服務器上的組件交互。代理模式可用來與外部服務交互。

          你要小心有要暴露你應用的模型,因為有些惡意用戶會用逆反工程危及你服務器的組件。就象其它WEB應用一樣,當交換敏感信息的時候,考慮使用 HTTPS來保護連接。

          我什么時候用同步請求而不用異步請求?

          問得好。叫它AJAX是有道理的。一個同步請求會堵塞頁面的事件處理,我還沒發現很多同步比異步好的用例。

          那些applet和plugin該怎么辦?

          不要急于拋棄基于 applet 和 plugin 的應用。盡管AJAX 和 DHTML 能夠實現拖放效果和其它高級用戶界面功能,但它們仍然有局限性,特別是在瀏覽器支持方面。Plugin 和 applet 已經存在了一段時間,而且一直都能實現類似于AJAX 請求的功能。Applet 提供了開發員所需要的一系列優秀的用戶界面組件和API。

          許多人不愿意用 applet 或者 plugin,因為它們啟動的時候需要等一段時間,而且無法保證應用需要的JVM plugin 版本已被安裝。Plugin 和 applet 可能在操縱 DOM 上有欠缺。如果你在一個統一的環境下,或者你可以肯定你的應用能找到一個特定版本的JVM plugin(比如在一個公司內部環境),那么 plugin 或 applet 就一失為一個良好的解決方案。

          還有一種選擇是把AJAX和 applet 或? plugin 混合起來使用。Flickr 就是這樣,一方面用 AJAX 交互或者 DHTML 來標識圖形和與用戶交流,另一方面用一個 plugin 來管理照片,從面提供了極好的用戶體驗。如果服務器端組件設計得好的話,它們可以同時與這兩種客戶會話。

          該怎樣處理向前和向后按鈕?

          你可以開發自己的方案在應用中追蹤當前的狀態,但是我建議你還是把這種任務留給專家來做。Dojo 以不待定于瀏覽器的方式來處理導航問題,如下所示:

          function updateOnServer(oldId, oldValue, itemId, itemValue) {
          var bindArgs = {
          url: "faces/ajax-dlabel-update",
          method: "post",
          content: {"component-id": itemId, "component-value": itemValue},
          mimetype: "text/xml",
          load: function(type, data) {
          processUpdateResponse(data);
          },
          backButton: function() {
          alert("old itemid was " + oldId);
          },
          forwardButton: function(){
          alert("forward we must go!");
          }
          };
          dojo.io.bind(bindArgs);
          }

          上面的例子用到了 dojo.io.bind() 來更改服務端的一個值,dojo.io.bind()? 還用到了一個函數來負責處理瀏覽器向后按鈕事件。這樣作為一個開發員你就可以在上例中恢復以前的值(oldValue),或者采取其它合適的行動。開發員不用關注怎樣察覺到瀏覽器按鈕事件這些底層細節,因為Dojo已經處理掉了。

          AJAX: How to Handle Bookmarks and Back Buttons 這篇文章詳細介紹了這個問題,并提供了一個專門注重向前和后退問題的 JavaScript 庫。

          用AJAX怎樣發送圖像?


          當類似 Google Maps 的應用使用AJAX時,它們看上去似乎在發送圖像,事實上,針對AJAX請求,圖像URL作為響應被發送回去,然后通過DHTML來設置顯示圖像。

          在這個例子中,AJAX 交互返回了一個XML 文檔,然后填充 category 一欄。

          <categories>
          <category>
          <cat-id>1</cat-id>
          <name>Books</name>
          <description>Fun to read</description>
          <image-url>books_icon.gif</image-url>
          </category>
          <category>
          <cat-id>2</cat-id>
          <name>Electronics</name>
          <description>Must have gadgets</description>
          <image-url>electronics.gif</image-url>
          </category>
          </categories>

          請注意image-url元素包含了代表category元素的圖像的URL。AJAX交互的回調函數會解析作為響應的 XML文檔,并針對包括在XML響應文檔中的每個category調用addCategory函數。addCategory函數在頁面主體中查找一個叫"categoryTable" 的表格行元素,把以上的圖像作為新的一行加進去。

          <scrip type="text/javascript" >

          ...

          function addCategory(id, name, imageSrc) {

          var categoryTable = document.getElementById("categoryTable");
          var row = document.createElement("tr");
          var catCell = document.createElement("td");
          var img = document.createElement("img");
          img.src = ("images\\" + imageSrc);
          var link = document.createElement("a");
          link.className ="category";
          link.appendChild(document.createTextNode(name));
          link.setAttribute("onclick", "catalog?command=category&catid=" + id);
          catCell.appendChild(img);
          catCell.appendChild(link);
          row.appendChild(catCell);
          categoryTable.appendChild(row);
          }
          </script>

          ...

          <table>
          <tr>
          <td width="300" bgoclor="lightGray">
          <table id="categoryTable" border="0" cellpadding="0"></table>
          </td>
          <td id="body" width="100%">Body Here</td>
          </tr>
          </table>

          請注意到image source元素被設成了圖像的來源。接下來當img元素被加到categoryTable時,頁面會發出一個HTTP請求來載入位于"images/books_icon.gif" 或 "images/electronic_icon.gif" 的圖像。

          該怎樣創建一個線程來實現AJAX輪詢(polling)?

          JavaScript 沒有線程。當頁面叫發生某種事件時,比如頁面載入,鼠標點擊,或表單元素獲取輸入焦點, JavaScript 的函數會被調用。你可以用
          setTimeout 來建立一個定時器,這個函數用到兩個參數:另外一個函數的名字和毫秒數。這樣你就可以循環調用同一個函數,如下所示:

          function checkForMessage() {
          // start AJAX interaction with processCallback as the callback function
          }

          // callback for the request
          function processCallback() {

          // do post processing

          setTimeout("checkForMessage()", 10000);
          }

          請注意checkForMessage會一直無限制循環下去。根據你頁面的活動或用例,你可能需要改變一下間隔時間。你可能需要針對處理AJAX響應的某些條件來安排邏輯中斷循環。

          posted on 2006-07-04 13:53 wml 閱讀(690) 評論(0)  編輯  收藏 所屬分類: AJAX

          主站蜘蛛池模板: 卓尼县| 板桥市| 米林县| 昌图县| 塘沽区| 唐河县| 屏东市| 滁州市| 龙州县| 西乡县| 塘沽区| 西贡区| 丹阳市| 喀喇| 仁布县| 苍溪县| 三门县| 昆山市| 玉树县| 凤凰县| 弋阳县| 东丽区| 永福县| 唐海县| 上思县| 历史| 岑巩县| 乌海市| 荔波县| 屯门区| 嘉兴市| 六枝特区| 北票市| 潮州市| 荃湾区| 孟连| 尚志市| 越西县| 万盛区| 酒泉市| 兰坪|