﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-wml-文章分类-AJAX</title><link>http://www.blogjava.net/wml/category/12736.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 03:40:28 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 03:40:28 GMT</pubDate><ttl>60</ttl><item><title>转：Java 开发员AJAX 常见问题</title><link>http://www.blogjava.net/wml/articles/56527.html</link><dc:creator>wml</dc:creator><author>wml</author><pubDate>Tue, 04 Jul 2006 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/wml/articles/56527.html</guid><description><![CDATA[
		<h1>Java 开发员AJAX 常见问题</h1>
		<h3>作者: <a href="http://weblogs.java.net/blog/gmurray71/">Greg Murray</a>  译者：<a href="http://weblogs.java.net/blog/gmurray71/"></a><a href="http://blogs.sun.com/roller/page/chengfang">Cheng Fang</a><br /></h3>
		<p>原文：<a href="https://blueprints.dev.java.net/ajax-faq.html">https://blueprints.dev.java.net/ajax-faq.html</a><br /></p>
		<p>现在我们都有机会用AJAX 了，好多人发现这是个全新的世界。许多开发员会通过现有的框架来接触到AJAX ，或许你想深入钻研，扩充现有的功能。这些常见问题就是针对想在应用内加上AJAX 功能的开发员的。</p>
		<ol>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#shouldi">我应该考虑用 AJAX吗?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#java">AJAX 能不能和Java一起用?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#frameworks">难道我的框架不提供AJAX吗?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#ajax">该从哪里开始?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#know">创建我自己的AJAX功能，我要知道些什么?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#javascript">我真的需要学JavaScript吗?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#ajax-libraries">有哪些 JavaScript 库和框架可以帮助Java开发员?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#return_type">我应该使用哪种返回值类型, XML 或 text, JavaScript, 或 HTML?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#usability">AJAX 用起来方便不方便?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#testing">我该怎样调试 JavaScript?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#get_or_post">在AJAX调用中，我应该用HTTP GET还是 POST?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#i18n">我该怎样提供国际化的AJAX交互?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#concurrent_requests">我该如何处理并发的AJAX 请求?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#return_content_type">在服务器端怎样和AJAX客户端交流?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#state">针对 AJAX 客户，在哪里储存状态?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#partial_submit">怎样提交表单或表单的一部分，但不刷新页面？</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#controller">服务器端和客户端，谁有控制权?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#security">AJAX 在安全性方面有没有问题?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#synchronous">我什么时候用同步请求而不用异步请求？</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#applets">那些 applet和plugin该怎么办?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#navigation">该怎样处理向前和向后<font size="-1">按钮</font>?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#images">用AJAX 怎样发送图像?</a>
				</li>
				<li>
						<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#threading">该怎样创建一个线程来实现AJAX轮询（polling）?</a>
				</li>
		</ol>
		<h2>
				<a name="shouldi">我应该考虑用 AJAX吗?</a>
		</h2>
		<p>AJAX现在当然很红，但它不一定适合你。AJAX只能用在最新的浏览器上，暴露出许多浏览器兼容性问题，对许多人它还要求学会一些新技术。Alex Bosworth 写了篇不错的网志 <a href="http://sourcelabs.com/ajb/archives/2005/05/ajax_mistakes.html">AJAX Mistakes</a>，在你全力投入AJAX以前值得一看。 </p>
		<p>另一方面，你可以实现丰富的，高度交互性的，快速响应的WEB应用，它们看起来<a href="http://me.eae.net/archive/2005/04/02/xml-http-performance-and-caching/">真的很快</a>。尽管人们还在争论基于AJAX的应用是不是真的更快, 用户已感到更直接了，因为当数据在后台交换的时候，用户就收到了积极反馈。如果你较早采用了AJAX，能够处理浏览器兼容性问题，而且愿意学习一些新技术，那么AJAX是适合你的。谨慎起见，你可以试着把应用的一小部分或者小组件转化成AJAX。我们都喜欢新技术，但要记住AJAX的目的是要改善而不是妨碍用户的体验。<br /></p>
		<h2>
				<a name="java">AJAX 能不能和Java一起用?</a>
		</h2>
		<p>当然。Java很适合AJAX！你可以用Java企业版服务器来生成AJAX 客户端页面并处理进来的请求，为AJAX 客户端管理服务器端的状态，并且把AJAX 客户端联接到企业资源。<a href="http://java.sun.com/j2ee/javaserverfaces/index.jsp">JavaServer Faces</a> 组件模型非常适合于定义和使用AJAX组件。<br /></p>
		<h2>
				<a name="frameworks">难道我的框架不提供AJAX吗?</a>
		</h2>你可能已经受益于AJAX。许多现有的基于Java 的框架已经有一定的AJAX 交互，许多新的框架和组件正在被开发来更好地支持AJAX。这里我不想列出所有用AJAX 的Java框架，因为我怕会遗漏一些。但是你可以在这里找到一个不错的列单： <a href="http://ajaxpatterns.org/Java_Ajax_Frameworks">www.ajaxpatterns.org/Java_Ajax_Frameworks</a>. 
<p>如果你还没有选好一个框架，我建议你考虑使用<a href="http://bpcatalog.dev.java.net/nonav/ajax/jsf-ajax/frames.html">JavaServer Faces</a> 或者基于JavaServer Faces的框架。你可以用JavaServer Faces组件来抽象化处理许多细节：生成JavaScript, AJAX交互, 和<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#DHTML">DHTML</a>处理，这样JSF开发员就可以更方便地使用AJAX，它们还可以作为插件装入支持JSF的IDE内，比如 <a href="http://developers.sun.com/prodtech/javatools/jscreator/index.jsp">Sun Java Studio Creator</a>. </p><h2><a name="ajax">该从哪里开始?</a></h2><p>如果你现在的框架不能满足你的用例，你想开发自己的AJAX组件和功能，我建议你先看一下这篇文章<a href="http://java.sun.com/developer/technicalArticles/J2EE/AJAX/">Asynchronous JavaScript Technology and XML (AJAX) With Java 2 Platform, Enterprise Edition</a>。（译者注：中文版 <a href="http://www.uuzone.com/blog/555080192/39739.htm">在Java2平台企业版中应用异步 JavaScript技术和XML（AJAX）</a>） </p><p>如果你想看一个很基本的例子和源代码，这里有 <a href="http://java.sun.com/developer/EJTechTips/2005/tt1122.html#1">Using AJAX with Java Technology</a>。 <a href="http://java.sun.com/blueprints/ajax.html">Blueprints AJAX Home</a> 有更完整的AJAX资源。</p><p>接下来，我建议你花些时间研究<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#ajax-libraries">AJAX库和框架</a>。如果你想自己写AJAX客户端脚本，最好不要再重复劳动了。<br /></p><p>Dave Crane，Eric Pascarello和Darren James的<a href="http://manning.com/books/crane">AJAX in Action</a>也不错。这本书有附录中讲学习 JavaScript，对Java开发员有帮助。 </p><h2><a name="know">创建我自己的AJAX 功能，我要知道些什么?</a></h2><p>如果你不想利用已有的AJAX组件，这里是一些需要注意的地方。 </p><p>准备学习动态<a name="DHTML">HTML</a> (<a href="http://en.wikipedia.org/wiki/DHTML">DHTML</a>)， AJAX的基础技术。DHTML让用户与网页间通过浏览器现时交互成为可能。DHTML结合了JavaScript，文档对象模型(DOM)和层叠样式表 (CSS). </p><ul><li><a href="http://en.wikipedia.org/wiki/JavaScript">JavaScript</a> - JavaScript是个宽松类型的，基于对象的脚本语言。它是AJAX交互的关键，而且所有的主流浏览器都支持它。当页面中的一个事件发生时，例如，载入页面，鼠标点击，或表单元素上的按键，JavaScript就被调用了。 
</li><li><a href="http://en.wikipedia.org/wiki/Document_Object_Model">文档对象模型(DOM)</a> - 用来读取和更改结构化文档的应用编程接口。在大多数情况下DOM代表XML和HTML文档的结构。<br /></li><li><a href="http://en.wikipedia.org/wiki/Cascading_Style_Sheets">层叠样式表(CSS)</a> - 让你定义页面的外观，例如：字体，颜色，大小，和定位。CSS让你清晰地分隔开内容和形式，并且可以用JavaScript来编程改变。 </li></ul><p>理解<a href="http://en.wikipedia.org/wiki/HTTP">HTTP</a>的请求/回应这一基本性质也很重要。如果你在配置<a href="http://en.wikipedia.org/wiki/XMLHttpRequest">XMLHttpRequest</a>时忽略了GET和POST方法的区别，或者在处理回调时忽略了HTTP状态代码，你会碰到许多难题。<br /></p><p>从某种意义上说，JavaScript是一种客户端的胶合体。JavaScript被用来创建XMLHttpRequest对象并触发异步调用。 JavaScript被用来解析返回的内容。JavaScript被用来分析返回的数据并处理返回的信息。用JavaScript可以通过DOM API往HTML里注入内容和改变CSS。</p><h2><a name="javascript">我真的需要学JavaScript吗?</a></h2><p>一般来说，是的，如果你想为你的WEB应用开发新的AJAX功能。<br /></p><p>另外一方面， <a href="http://bpcatalog.dev.java.net/nonav/ajax/jsf-ajax/frames.html">JSF 组件</a>和组件库能抽象化JavaScript，DOM和CSS的细节。这些组件能生成必要的工件（artifacts）来支持AJAX交互。可视的工具，象<a href="http://developer.sun.com/prodtech/javatools/jscreator/index.jsp">Java Studio Creator</a>，也可以利用支持AJAX的JSF组件来创建应用，应用开发者就不用担心AJAX的许多细节了。如果你打算写自己的 JSF组件，或者想把组件间的事件串联在一起，你应该对JavaScript有个基本了解。你可以从你页面里的JavaScript调用一些客户端的<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#ajax-libraries">JavaScript 库</a>（在下面谈到）来抽象化测声器间的差异。 <a href="http://www.cs.rit.edu/%7Eatk/JavaScript/manuals/jsobj/index.htm">Object Hierarchy and Inheritance in JavaScript</a> 是一个供Java开发员学习JavaScript对象的很好的参考。<br /></p><h2><a name="ajax-libraries">有哪些JavaScript 库和框架可以帮助Java开发员?</a></h2>已经有许多库和框架（而且许多还在涌现出来）能帮助我们抽象化这些讨厌的浏览器差异。三个不错的库是：The Dojo Toolkit, Prototype, and DWR. 
<ul><li><a name="dojo"></a><a href="http://dojotoolkit.org/">The Dojo Toolkit</a> 包含一些API和工具来支持开发富WEB应用。Dojo包含一个智能的包装系统，用户界面效果，拖放方法(Drag and Drop) API，小应用（widget）API，事件抽象，客户存储API，以及AJAX交互API。Dojo解决了一些常见的可用性(Usability)问题， 比如，处理浏览器导航问题包括察觉浏览器退后按钮，更改地址栏里的URL来收藏书签，当客户端不完全支持AJAX和JavaScript时妥善处理。Dojo就好比是JavaScript库中的一把瑞士军刀。 它在一个库里提供了最广泛的选择，而且能很好地支持新老浏览器。 </li></ul><ul><li><a name="prototype"></a><a href="http://prototype.conio.net/">Prototype</a> 专注于通过JavaScript AJAX对象进行AJAX 交互，它包含了若干对象来做基本的工作，比如发出请求，更新部分文档，往文档里插入内容，以及定期更新部分文档。Prototype JavaScript库包含了一套JavaScript对象来代表AJAX请求，和一些效用函数来读取页面内的数据和修改DOM。 <a href="http://script.aculo.us/">Script.aculo.us</a>和<a href="http://openrico.org/">Rico</a>就是建立在Prototype之上并提供了用户界面效果，支持拖放效果，以及一些围绕JavaScript的不工具（widgets)。如果你想支持AJAX交互和一些基本的功能，Prototype是个很好的选择。如果你需要用户界面效果，Script.aculo.us和Rico是不错的。<br /><br /></li><li><a name="yui"></a><a href="http://developer.yahoo.net/yui/index.html/">Yahoo UI Library</a> 是一个通过API来支持富客户端的效用库和一套小应用。这个效用库包括了支持跨浏览器的AJAX交互，动画，DOM脚本，拖放，以及跨浏览器事件。 Yahoo UI Library提供较好的文档和许多例子。<br /><br /></li><li><a name="dwr"></a><a href="http://dwr.dev.java.net/">DWR (Dynamic Web Remoting)</a> 是一个客户端和服务器端的框架，它专注于允许开发员实现从客户端JavaScript到J2EE WEB容器内的普通Java对象（Plain Old Java Object）之间的远程调用。在服务器端，DWR用一个Servlet来和Java对象交互，并返回Java对象或做成了对象的XML文档。 DWR安装使用方便，和其它Java技术配合较好。如果你想要一个整合性能良好，同时支持客户端和服务器的框架，那就用 DWR. <br /><br /></li><li><a name="zimbra"></a><a href="http://dwr.dev.java.net/">Zimbra</a> 是个客户端和服务器的框架，它专注于支持消息（messaging），包括向使用JavaScript的客户端提供电子邮件服务。在它的工具包中有抽象化浏览器差异的UI API（同时也包括了许多内在的小应用），支持UI事件通信和客户与服务器之间通信的API，简化客户端JavaScript开发的效用类，抽象化了的 DOM API以简化跨浏览器操作，和一套网络API来帮助JavaScript客户端AJAX和SOAP通信。 </li></ul><p>有好多新的JavaScript库正在涌现出来，以上只是回顾了比较常见的库。选择最适合你需要的。尽管你最好用一个框架，当然也可以同时用多个。更详细的客户端框架列单，请看：<a href="http://wiki.osafoundation.org/bin/view/Projects/AjaxLibraries">Survey of AJAX/JavaScript Libraries</a>. </p><h2><a name="return_type">我应该使用哪种返回值类型, XML 或 text, JavaScript, 或 HTML?</a></h2><p>这要看情况。很清楚，AJAX里的X代表了XML，但是一些AJAX支持者马上也指出，AJAX本身并不排除使用其它种类做载荷（PAYLOAD），比如，JavaScript, HTML, 或是纯文本格式。<br /></p><ul><li>XML - Web Services和AJAX看起来天生般配。你可以用客户端的API来下载和解析来自<a href="http://en.wikipedia.org/wiki/REST">REST</a>一类Web Services的XML内容。（不过，要小心在有些基于<a href="http://en.wikipedia.org/wiki/SOAP">SOAP</a>的Web Services中载荷会变得又大又复杂，所以不适合AJAX技术）。 
</li><li>纯文本格式 - 在种情况下，服务器产生的文本被注入文档中，或用客户端逻辑来评估。 
</li><li>JavaScript - 是纯文本格式的延伸，不过服务器端组件会传递JavaScript脚本的分段，包括JavaScript对象声明。你可以在客户端用JavaScript <code>eval()函数来创建这些对象。</code><a href="http://en.wikipedia.org/wiki/JSON" name="JSON">JSON</a>，一个基于 JavaScript对象的数据交换规范，就是依赖了这种技术。 
</li><li>HTML - 直接把服务器生成的HTML分段注入文档，这通常是一种很有效的AJAX方法。不过，要让服务器端的组件和客户端的显示内容保持一致会有点复杂。<br /></li></ul><p><a href="http://en.wikipedia.org/wiki/Mashup_%28web_application_hybrid%29">网络聚合(Mashup)</a> 这是一个时下流行的术语，它从离散的WEB SERVICES和其它在线API获取内容，结合在一起创建全新的WEB应用。 一个很好的网络聚合的例子就是<a href="http://www.housingmaps.com/">housingmaps.com</a>，它把<a href="http://www.craigslist.org/">craiglist.org</a> 的住房广告和 <a href="http://maps.google.com/">maps.google.com</a>的地图结合在一起。</p><h2><a name="usability">AJAX用起来方便不方便?</a></h2><p>通过AJAX交互和DHTML的途径来获取数据，动态更新页面，这在本质上是会大幅度地改变页面的外观和状态。用户可能会在任何时候用到浏览器的向前或退后按钮，书签收藏当前页面，从地址栏复制URL后通过电子邮件或聊天发给朋友，或者是打印页面。在设计AJAX应用时，你应该考虑在发生这些情况时你预期的结果是怎样：导航，书签收藏，打印，浏览器支持， 如下所述：<br /></p><ul><li>导航- 向前，退后，刷新和书签收藏这些浏览器按钮被点击时，你应用设计预期的结果是什么？你虽然可以用<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#navigation">手工地</a>实现一些历史控制，但更简便的方法是用一些能提供历史和导航控制API的JavaScript框架，比如<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#dojo">Dojo</a>。<br /></li><li>书签收藏和URL分享 - 许多用户想书签收藏或从地址栏里拷贝URL。<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#dojo">Dojo</a> 支持客户端书签收藏和修改URL。 
</li><li>打印- 有些时候打印动态产生的页面会有问题。 </li></ul><p>开发员使用AJAX时其它考虑因素： </p><ul><li>浏览器支持 - 并不是所有的浏览器，或一个浏览器的所有版本都支持所有的AJAX或DHTML功能。<a href="http://www.quirksmode.org/">quirksmode.org</a> 列举了浏览器支持情况和可能的变通方法。 
</li><li>JavaScript被关闭 - 你还应该考虑如果用户关闭使用JavaScript，你该怎么办。另外，有些用户的浏览器上因为有些原因不能支持JavaScript和CSS。 
</li><li>等待时间（Latency) - 在你的设计中应该考虑到等待时间。应用在运行时应该比部署时更加响应迅速。同时要考虑到发出多个请求时，返回的次序是没有保障的。详情请看<a href="http://richui.blogspot.com/2005/09/ajax-latency-problems-myth-or-reality.html">AJAX Latency problems: myth or reality?</a></li><li>可访问性 - 确保你的网站能让有残障的人访问，这不光是一个高尚的目标，在很多地区也是法律。有许多优秀的支撑技术能帮助他们使用网络，尽管他们有视觉，听觉，体力，语言，认知和神经方面的残障。有一点前瞻性，理解这方面的丰富文档和最好实践，你就能确保你的应用符合这些支撑技术的要求。 </li></ul><p>降解效果(Degradability)这个术语描述了WEB应用用于适应广泛的浏览器功能的一系列技巧。许多AJAX库有内置的自动降解方式。如果你要写自己的AJAX功能，考虑采纳一些标准组织，比如World Wide Web Conrsoritum (<a href="http://www.w3.org/">W3C)</a>, 和草根运动，比如<a href="http://www.webstandards.org/">Web Standards</a>和其它人的最佳实践。这样你的应用在不支持AJAX的浏览器上仍然能运行，虽然它失去了一些很抢眼的效果。<br /></p><p>记住不要只是为了显得酷而用AJAX。你打造WEB应用是为了给人用的。如果和他们的浏览器上不兼容，用户就不会用你的应用。 </p><h2><a name="testing">我该怎样调试 JavaScript?</a></h2><p>没有很多调试器能同时支持客户端和服务器端调试。我肯定随着AJAX的普及，这种情况会改变。我现在分开调试客户端和服务器。以下是一些关于常见浏览器上的客户端调试器的情况：<br /></p><ul><li>Firefox/Mozilla/Netscape - 在一个内置的调试器<a href="http://www.mozilla.org/projects/venkman/">Venkman</a>很有帮助。我喜欢先在 Firefox开发应用，然后再到其它浏览器上去试。 
</li><li>Safari - 有一个调试器，你需要先开户。详情请看<a href="http://developer.apple.com/internet/safari/faq.html#anchor14">Safari FAQ</a>。<br /></li><li>Internet Explorer - <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdbug/Html/sdbug_12.asp">MSDN Documentation</a>上有关于调试JavaScript的文档。<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&amp;displaylang=en">Internet Explorer developer toolbar</a>可能也有帮助。<br /></li></ul><p>除了调试器能帮忙，还有一种常用的方法叫“对话框调试（Alert Debugging）”。在这种情况下你加入"alert()"函数调用，就好比在JAVA中用System.out.println一样。尽管是一个很小的窍门，对大部分情况都管用。有些框架，象<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#dojo">Dojo</a>，提供 API来追踪调试语句。 </p><h2><a name="get_or_post">在AJAX调用中，我应该用HTTP GET还是 POST?</a></h2><p>如果相对于一个待定的URL的数据一会改变，那么AJAX请求应该用HTTP GET方法。如果服务器会更新状态，那么就应该用HTTP POST方法。这和<a href="http://www.w3.org/DesignIssues/Architecture.html#Content">HTTP idempotency recommendations</a>的要求是一致的，也是大家为创造一个统一的WEB应用设计而高度推荐的做法。 </p><h2><a name="i18n">我该怎样提供国际化的AJAX交互?</a></h2><p>不能认为用了XML， 你就能以AJAX请求发送和获取区域化的内容。要提供国际化的AJAX组件，你需要做以下这些要求：<br /></p><ul><li>把页面字符集设成目标语言支持的编码。你趋向于使用UTF-8，因为它涵盖了在部分语言。以下一个HTML/JSP页面的meta声明设置了 content type： <pre>    &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;<br /></pre></li><li>在页面内JavaScript确保每个发往服务器的参数都被编码。JavaScript提供了一个<code>escape()函数来返回统一码(UNICODE)转义字符串，这样区域化的文本就以</code>十六进制的格式出现。更多关于JavaScript编码的信息，请看<a href="http://xkr.us/articles/javascript/encode-compare/">Comparing escape(), encodeURI(), and encodeURIComponent()</a>. </li></ul><ul><li>服务器端组件用HttpServletRequest.setCharacterEncoding()方法设置字符编码。这必须发生在用 HttpServletRequest.getParameter()方法读取区域化参数以前。如果是UTF-8，那就应该是 <code>request.setCharactherEncoding("UTF-8");</code>. </li></ul><p>返回AJAX回应的服务器端组件需要把回应的编码设成和该页面一样的编码。</p><pre>    response.setContentType("text/xml;charset=;UTF-8");<br />    response.getWriter().write("&lt;response&gt;invalid&lt;/response&gt;"); <br /></pre><p>关于在Java企业版上使用AJAX，更多资料请看<a href="http://bpcatalog.dev.java.net/ajax/i18n/">AJAX and Internationalization</a>，开发多种语言应用，请看<a href="http://java.sun.com/developer/technicalArticles/Intl/MultilingualJSP/">Developing Multilingual Web Applications Using JavaServer Pages Technology</a>. </p><h2><a name="concurrent_requests">我该如何处理并发的AJAX 请求?</a><br /></h2><p>通过JavaScript你可以同时处理多个AJAX 请求。为了确保妥善的后处理，我建议使用<a href="http://jibbering.com/faq/faq_notes/closures.html">JavaScript闭包（JavaScript Closures</a>）。下面这个例子显示了一个XMLHttpRequest 被抽象化为JavaScript对象<code>AJAXInteraction</code>。传进的参数是要调用的URL和处理结束后要调用的函数。</p><pre>function AJAXInteraction(url, callback) {<br /><br />    var req = init();<br />    req.onreadystatechange = processRequest;<br /><br />    function init() {<br />      if (window.XMLHttpRequest) {<br />        return new XMLHttpRequest();<br />      } else if (window.ActiveXObject) {<br />        return new ActiveXObject("Microsoft.XMLHTTP");<br />      }<br />    }<br /><br />    function processRequest () {<br />      if (req.readyState == 4) {<br />        if (req.status == 200) {<br />          if (callback) callback(req.responseXML);<br />        }<br />      }<br />    }<br /><br />    this.doGet = function() {<br />      req.open("GET", url, true);<br />      req.send(null);<br />    }<br /><br />    this.doPost = function(body) {<br />      req.open("POST", url, true);<br />      req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");<br />      req.send(body);<br />    }<br />}<br /><br />function makeRequest() {<br />  var ai = new AJAXInteraction("processme", function() { alert("Doing Post Process");});<br />  ai.doGet();<br />}<br /><br /></pre><p>在上例中，<code>makeRequest()函数创建了一个</code><code>AJAXInteraction</code>，传入两个参数：要调用的URL“processme”和一个内联函数。这个内联函数会弹出对话框来显示信息"Doing Post Process"。调用<code>ai.doGet()</code>就启动了AJAX 互动，当映射到URL "processme" 的服务器端组件返回一个文档，这个文档再被传给<code>创建这个</code><code>AJAXInteraction时指定的回调函数。</code><span style="FONT-FAMILY: monospace"><br /></span></p><p><span style="FONT-FAMILY: monospace"></span>使用这样的闭包能确保对应于一特定的AJAX交互的回调函数能被正确调用。当你使用多个闭包对象来做XmlHttpRequests时仍需小心，因为在任何一特定时刻都只有有限的套接字（SOCKET）用来发出请求。因为只能有有限数目的并行请求，Internet Explorer只允许任何时刻最多<a href="http://support.microsoft.com/kb/183110">两个并行AJAX请求</a> 。其它浏览器可能会允许更多，但一般是三个到五个之间。你也可以用<a href="http://blog.joshuaeichorn.com/archives/2005/04/22/improving-jpspan-performance-with-an-object-pool/">池</a>来管理AJAXInteraction对象。<br /></p><p>有一点要注意，当从客户端发出多个AJAX请求时，它们的返回值没有特定的次序。在回调函数中使用闭包能确保这些信赖能被正确处理。<br /></p><p>这个讨论很有帮助<a href="http://www.ajaxian.com/archives/2005/09/ajaxian_fire_an.html">Ajaxian Fire and Forget Pattern</a>。<br /></p><h2><a name="return_content_type">在服务器端怎样和AJAX客户端交流?</a></h2><p><br />对于返回值类型XML，"Content-Type" 要设成"text/xml"。在SERVLET里可以用 <code>HttpServletReqponse.setContentType()</code>。许多XMLHttpRequest 实现如果发现"Content-Type"已经设了会报错。一面的代码显示了如何设"Content-Type"： </p><pre>    response.setContentType("text/xml");<br />    response.getWriter().write("&lt;response&gt;invalid&lt;/response&gt;"); <br /></pre><p>你可能要考虑是不是要设缓存标头。在些时候，比如自动补全，你可能要通知代理服务器和浏览器不要缓存结果。<br /></p><pre>    response.setContentType("text/xml");<br />    response.setHeader("Cache-Control", "no-cache");<br />    response.getWriter().write("&lt;response&gt;invalid&lt;/response&gt;"); <br /></pre>开发员注意：如果这个标头没有设，Internet Explorer 对于HTTP GET方法的响应会自动用缓存的结果。这可能会引起一些问题。所以在开发的时候你可能要设这个标头。 
<h2><a name="state">针对AJAX客户，在哪里储存状态?</a></h2><p>和任何基于浏览器的WEB应用一样，你有以下这些选择： </p><ul><li>在客户端使用cookie - 大小有限（一般是每个域名20个cookie ，每个cookie 4KB，总共80KB）。除非加密，否则不安全。加密是困难的，但用JavaScript也不是不可能。<br /></li><li>在客户端页面中 - 这种方法安全，但用起来困难，容易出问题。我的一篇网志有更详细的讨论：<a href="http://weblogs.java.net/blog/gmurray71/archive/2005/05/storing_secure.html">Storing State on the Client</a>。<br /></li><li>在客户端文件系统内 - 如果浏览器已有权限写往本地文件系统，这是可行的。取决于你的用例，这可能也就够了，但也需谨慎。 
</li><li>在服务器端 - 这和传统模式最想象：客户的状态保存在服务器上。如何保持数据一致会是个问题，所以我们针对这设计了这样一种方案<a href="http://bpcatalog.dev.java.net/nonav/ajax/refreshing-data/design.html">Refreshing Data</a>。当我们把更多的数据处理移往客户端时，就需要重新评估在哪里储存状态。 </li></ul><h2><a name="partial_submit">怎样提交表单或表单的一部分，但不刷新页面？</a></h2><p>当建立表单的时候，要确保"form"元素的"onSubmit"属性设成一个返回false的JavaScript函数。 </p><pre>  &lt;form onSubmit="doAJAXSubmit();return false;" &gt;<br />   &lt;input type="text" id="tf1" /&gt;<br />   &lt;input type="submit" id="submit1" value="Update"/&gt;<br />  &lt;/&gt;<br /></pre><p>用同样的方法，你也可以联接函数和表单按钮，从而来提交表单： </p><pre>  &lt;form onSubmit="doAJAXSubmit();return false;" &gt;<br />   &lt;input type="text" id="tf1" /&gt;<br />   &lt;input type="button" id="button1" onClick="doAJAXSubmit()" value="Update"/&gt;<br />  &lt;/&gt;<br /></pre><p>注意：表单上的"onSubmit"属性已被设置。如果用户在文本输入框中按了回车，表单也会被提交。所以你要处理这种情况。 </p><p>当更新页面时，我建议你等到确保AJAX已经顺利更新了表单数据后再更新页面数据。否则，数据可能没有适当更新，用户却不知道。我喜欢在做部分更新时给用户一个提醒信息，等AJAX交互顺利结束后，再更新页面。 </p><h2><a name="controller">服务器端和客户端，谁有控制权?</a></h2><p>这要看情况而定。对于AJAX来说，答案在两者中间。服务器端组件可实施更强的中央控制，或者服务器端和客户端一起来控制。 </p><ul><li>中央化的服务器端控制器 - 当你用一个更中央化的控制器时，关键是要确保客户端页面的数据和服务器端保持一致。有些应用在服务器保持状态，并把所有的更新通过一个简单的 JavaScript控制器推送到客户端的DOM。<br /></li><li>客户端和服务器端的控制器 - 这种设计会用JavaScript来做所有与表现有关的控制，事件处理，页面修改，并在客户端渲染显示业务数据。服务器端负责的事情包括业务逻辑，和把更新后的业务数据推送给客户。在这种情况下，服务器除了发送往客户的最初页面以外，并不熟悉表现层的情况，<br /></li></ul><br />在有些用例中，整个AJAX应用只有一个页面。但要记住，如果你选用了这种设计，务必考虑到浏览器导航和书签收藏。 
<p>取决于你想实现什么，这两种方法都可以采用。我趋向于让把控制分布到服务器端和客户端。 </p><h2><a name="security">AJAX在安全性方面有没有问题?</a></h2><p>用户通过查看页面源代码就可以看见JavaScript的源代码。没有用户赋予的权限，JavaScript不能访问本地文件系统。AJAX只能与提供该页面下载的服务器上的组件交互。代理模式可用来与外部服务交互。<br /></p><p>你要小心有要暴露你应用的模型，因为有些恶意用户会用逆反工程危及你服务器的组件。就象其它WEB应用一样，当交换敏感信息的时候，考虑使用 HTTPS来保护连接。<br /><br /></p><h2><a name="synchronous">我什么时候用同步请求而不用异步请求？</a></h2><p>问得好。叫它AJAX是有道理的。一个同步请求会堵塞页面的事件处理，我还没发现很多同步比异步好的用例。 </p><h2><a name="applets">那些applet和plugin该怎么办?</a></h2><p>不要急于抛弃基于 applet 和 plugin 的应用。尽管AJAX 和 DHTML 能够实现拖放效果和其它高级用户界面功能，但它们仍然有局限性，特别是在浏览器支持方面。Plugin 和 applet 已经存在了一段时间，而且一直都能实现类似于AJAX 请求的功能。Applet 提供了开发员所需要的一系列优秀的用户界面组件和API。<br /></p><p>许多人不愿意用 applet 或者 plugin，因为它们启动的时候需要等一段时间，而且无法保证应用需要的JVM plugin 版本已被安装。Plugin 和 applet 可能在操纵 DOM 上有欠缺。如果你在一个统一的环境下，或者你可以肯定你的应用能找到一个特定版本的JVM plugin（比如在一个公司内部环境），那么 plugin 或 applet 就一失为一个良好的解决方案。<br /></p><p>还有一种选择是把AJAX和 applet 或  plugin 混合起来使用。<a href="http://www.flickr.com/">Flickr</a> 就是这样，一方面用 AJAX 交互或者 DHTML 来标识图形和与用户交流，另一方面用一个 plugin 来管理照片，从面提供了极好的用户体验。如果服务器端组件设计得好的话，它们可以同时与这两种客户会话。</p><h2><a name="navigation">该怎样处理向前和向后按钮?</a></h2><p>你可以开发自己的方案在应用中追踪当前的状态，但是我建议你还是把这种任务留给专家来做。<a href="https://blueprints.dev.java.net/ajax-faq-zh.html#dojo">Dojo</a> 以不待定于浏览器的方式来处理导航问题，如下所示： </p><pre>function updateOnServer(oldId, oldValue, itemId, itemValue) {<br />    var bindArgs = {<br />        url:  "faces/ajax-dlabel-update",<br />        method: "post",<br />        content: {"component-id": itemId, "component-value": itemValue},<br />        mimetype: "text/xml",<br />	    load: function(type, data) {<br />               processUpdateResponse(data);<br />             },<br />        backButton: function() {<br />               alert("old itemid was " + oldId);<br />			},<br />        forwardButton: function(){<br />               alert("forward we must go!");<br />            }<br />     };<br />    dojo.io.bind(bindArgs);<br />}<br /></pre><p>上面的例子用到了 dojo.io.bind() 来更改服务端的一个值，dojo.io.bind()  还用到了一个函数来负责处理浏览器向后按钮事件。这样作为一个开发员你就可以在上例中恢复以前的值（oldValue），或者采取其它合适的行动。开发员不用关注怎样察觉到浏览器按钮事件这些底层细节，因为Dojo已经处理掉了。 </p><p><a href="http://www.onjava.com/pub/a/onjava/2005/10/26/ajax-handling-bookmarks-and-back-button.html?page=1">AJAX: How to Handle Bookmarks and Back Buttons</a> 这篇文章详细介绍了这个问题，并提供了一个专门注重向前和后退问题的 JavaScript 库。</p><h2><a name="images">用AJAX怎样发送图像?</a></h2><p><br />当类似 <a href="http://maps.google.com/">Google Maps</a> 的应用使用AJAX时，它们看上去似乎在发送图像，事实上，针对AJAX请求，图像URL作为响应被发送回去，然后通过DHTML来设置显示图像。<br /></p><p>在这个例子中，AJAX 交互返回了一个XML 文档，然后填充 category 一栏。<br /></p><pre>&lt;categories&gt;<br />&lt;category&gt;<br />  &lt;cat-id&gt;1&lt;/cat-id&gt;<br />  &lt;name&gt;Books&lt;/name&gt;<br />  &lt;description&gt;Fun to read&lt;/description&gt;<br />  &lt;image-url&gt;books_icon.gif&lt;/image-url&gt;<br /> &lt;/category&gt;<br />&lt;category&gt;<br />  &lt;cat-id&gt;2&lt;/cat-id&gt;<br />  &lt;name&gt;Electronics&lt;/name&gt;<br />  &lt;description&gt;Must have gadgets&lt;/description&gt;<br />  &lt;image-url&gt;electronics.gif&lt;/image-url&gt;<br /> &lt;/category&gt;<br />&lt;/categories&gt;<br /></pre><p>请注意<code>image-url元素包含了代表</code>category元素的图像的URL。AJAX交互的回调函数会解析作为响应的 XML文档，并针对包括在XML响应文档中的每个category调用<code>addCategory函数。</code><code>addCategory函数在页面主体中查找一个叫</code>"categoryTable" 的表格行元素，把以上的图像作为新的一行加进去。 </p><pre>&lt;scrip type="text/javascript" &gt;<br /><br />...<br /><br />function addCategory(id, name, imageSrc) {<br /><br />    var categoryTable = document.getElementById("categoryTable");<br />    var row = document.createElement("tr");<br />    var catCell = document.createElement("td");<br />    var img = document.createElement("img");<br />    img.src = ("images\\" + imageSrc);<br />    var link = document.createElement("a");<br />    link.className ="category";<br />    link.appendChild(document.createTextNode(name));<br />    link.setAttribute("onclick", "catalog?command=category&amp;catid=" + id);<br />    catCell.appendChild(img);<br />    catCell.appendChild(link);<br />    row.appendChild(catCell);<br />    categoryTable.appendChild(row);<br />}<br />&lt;/script&gt;<br /><br />...<br /><br />&lt;table&gt;<br /> &lt;tr&gt;<br />  &lt;td width="300" bgoclor="lightGray"&gt;<br />    &lt;table id="categoryTable" border="0" cellpadding="0"&gt;&lt;/table&gt;<br />  &lt;/td&gt;<br />  &lt;td id="body" width="100%"&gt;Body Here&lt;/td&gt;<br /> &lt;/tr&gt;<br />&lt;/table&gt;<br /></pre><p>请注意到image source元素被设成了图像的来源。接下来当img元素被加到<code>categoryTable</code>时，页面会发出一个HTTP请求来载入位于"images/books_icon.gif" 或 "images/electronic_icon.gif" 的图像。 </p><h2><a name="threading">该怎样创建一个线程来实现AJAX轮询（polling）?</a><br /></h2><p>JavaScript 没有线程。当页面叫发生某种事件时，比如页面载入，鼠标点击，或表单元素<font size="-1">获取输入焦点， JavaScript 的函数会被调用。你可以用<span style="FONT-FAMILY: monospace"><br /></span></font><code>setTimeout</code> 来建立一个定时器，这个函数用到两个参数：另外一个函数的名字和毫秒数。这样你就可以循环调用同一个函数，如下所示：</p><pre>function checkForMessage() {<br />  // start AJAX interaction with processCallback as the callback function<br />}<br /><br />// callback for the request<br />function processCallback() {<br /><br />    // do post processing<br /><br />    setTimeout("checkForMessage()", 10000);<br />}<br /></pre><p>请注意checkForMessage会一直无限制循环下去。根据你页面的活动或用例，你可能需要改变一下间隔时间。你可能需要针对处理AJAX响应的某些条件来安排逻辑中断循环。</p><img src ="http://www.blogjava.net/wml/aggbug/56527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wml/" target="_blank">wml</a> 2006-07-04 13:53 <a href="http://www.blogjava.net/wml/articles/56527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转：AJAX框架简介</title><link>http://www.blogjava.net/wml/articles/56498.html</link><dc:creator>wml</dc:creator><author>wml</author><pubDate>Tue, 04 Jul 2006 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/wml/articles/56498.html</guid><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td align="middle" bgcolor="#f7fbfe" colspan="2" height="40">
										<span style="FONT-SIZE: 16pt; COLOR: #05006c">
												<b>AJAX框架简介</b>
										</span>
								</td>
						</tr>
						<tr>
								<td class="table2 style3" align="middle" bgcolor="#f7fbfe" colspan="2" height="20">
										<a href="http://www.51cto.com/" target="_blank">
												<font color="#000000">http://www.51cto.com</font>
										</a>2006-03-17 09:17 出处:www.javaeye.com
<script language="javascript" src="/php/count.php?view=yes&amp;artID=23958"></script></td>
						</tr>
						<tr>
								<td align="middle" bgcolor="#f7fbfe" colspan="2" height="10">
								</td>
						</tr>
						<tr>
								<td align="left" bgcolor="#f7fbfe" colspan="2" height="0">
										<table class="shortmsg" cellspacing="0" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td class="shortmsg_td">【导读】DWR和Buffalo都是Web Remoting框架，区别在于DWR使用自定义的简单文本协议，而Buffalo使用burlap协议；DWR的服务器端实现要比Buffalo完善一些……</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
						<tr>
								<td align="middle" bgcolor="#f7fbfe" colspan="2" height="10">
								</td>
						</tr>
						<tr>
								<td valign="top" align="left" width="98%" bgcolor="#f7fbfe" height="142">
										<span class="top11">
												<p>
												</p>
												<p>
														<strong>AJAX框架</strong>
												</p>
												<ul>
														<li>DWR - Web Remoting 
</li>
														<li>Buffalo - Web Remoting (based on prototype) 
</li>
														<li>prototype - JS OO library 
</li>
														<li>openrico - JS UI component (based on prototype) 
</li>
														<li>dojo - JS library and UI component 
</li>
														<li>qooxdoo - JS UI component (C/S Style) 
</li>
														<li>YUL - JS UI component </li>
												</ul>
												<strong>Web Remoting - DWR vs Buffalo</strong>
												<p>DWR和Buffalo都是Web Remoting框架，区别在于： </p>
												<ul>
														<li>DWR使用自定义的简单文本协议，而Buffalo使用burlap协议。因此Buffalo解析大数据量可能会比较慢，然而可以适用于多种服务器端和客户端，并且burlap协议的完整性和支持的数据类型更加丰富 
</li>
														<li>Buffalo基于prototype，如果你的AJAX应用也是基于prototype，那么可以减少重复加载prototype的带宽，并且获得相当一致的编程概念 
</li>
														<li>DWR的服务器端实现要比Buffalo完善一些 
</li>
														<li>DWR更加通用一些，用户比较广，而Buffalo是国内的Michael写的，用户使用比较少(名气较小) 
</li>
														<li>建议使用buffalo，相对更加易用，然而服务器端功能有待完善 </li>
												</ul>
												<strong>JavaScript Component Library - prototype vs qooxdoo vs dojo vs YUL</strong>
												<ul>
														<li>prototype是一个非常优雅的JS库，定义了JS的面向对象扩展，DOM操作API，事件等等，之上还有rico/script.aculo.us实现一些JS组件功能和效果(不过目前还不是很完善)，以prototype为核心，形成了一个外围的各种各样的JS扩展库，是相当有前途的JS底层框架，值得推荐，prototype以及rico/script.aculo.us的一个特出特点就是非常易学易用，门槛很低，常常是一两行JS代码就可以搞定一个相关的功能。同时它也是RoR集成的AJAX JS库。 </li>
												</ul>
												<ul>
														<li>qooxdoo是一个功能很强的JS组件库，完全模仿Windows操作系统的GUI组件。特点是不通过常规的HTML来构造页面，完全使用JS以类似VB/Delphi风格的编程方式构造Web GUI界面，比较适合内网面向C/S风格的web应用，，而不适合面向Internet的界面多变风格的应用。qooxdoo的一个重大卖点在于qooxdoo将要提供一个FormDesigner的IDE，通过在IDE里面的可视化拖拽设计方式来自动生成C/S风格的web页面js代码。qooxdoo缺点是JS文件体积过大，超过200KB，初次下载会比较慢，而且并不适合Internet消费类网站。 </li>
												</ul>
												<ul>
														<li>dojo是一个各个方面相当完善的JS库，包括了JS本身的语言扩展，以及各个方面的工具类库，和比较完善的UI组件库，也被广泛应用在很多项目中，他的UI组件的特点是通过给html标签增加tag的方式进行扩展，而不是通过写JS来生成，dojo的API模仿Java类库的组织方式。dojo的优点就是库相当完善，发展时间也比较长，缺点是文件体积也比较大，200多KB，初次下载相当慢，此外，dojo的类库使用显得不是那么易用，至少给我的感觉是相当笨拙，特别是和prototype相比，更加显得难用。 </li>
												</ul>
												<ul>
														<li>YUL是Yahoo新近发布的AJAX组件库，也是一个包含了各个方面，从工具类库到通讯，到UI组件的综合性JS库。YUL的优势在于文档非常齐全，而且有Yahoo的支持，缺点是库目前还是不是很全，功能也不强大。 </li>
												</ul>
										</span>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/wml/aggbug/56498.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wml/" target="_blank">wml</a> 2006-07-04 11:23 <a href="http://www.blogjava.net/wml/articles/56498.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>