﻿<?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-花-随笔分类-Java</title><link>http://www.blogjava.net/hua/category/12540.html</link><description>即使世界明天毁灭，我也要在今天种下我的葡萄树。 </description><language>zh-cn</language><lastBuildDate>Wed, 25 Apr 2007 18:31:31 GMT</lastBuildDate><pubDate>Wed, 25 Apr 2007 18:31:31 GMT</pubDate><ttl>60</ttl><item><title>直接telnet 25端口发邮件</title><link>http://www.blogjava.net/hua/archive/2007/04/24/113200.html</link><dc:creator>花</dc:creator><author>花</author><pubDate>Tue, 24 Apr 2007 07:43:00 GMT</pubDate><guid>http://www.blogjava.net/hua/archive/2007/04/24/113200.html</guid><wfw:comment>http://www.blogjava.net/hua/comments/113200.html</wfw:comment><comments>http://www.blogjava.net/hua/archive/2007/04/24/113200.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hua/comments/commentRss/113200.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hua/services/trackbacks/113200.html</trackback:ping><description><![CDATA[<p>：）可以自己写个程序发邮件咯。用jmail控件也行。<br>下次说telnet上收邮件，可以做邮件到达提醒。：）偶们的oa里用得到哦。<br><br>使用以下命令启动&nbsp;TELNET&nbsp;会话：<br>Telnet&nbsp;xxx.xxx.xxx.xxx&nbsp;25<br>如果正常，您将会看到以下来自&nbsp;IMC&nbsp;的响应：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;220&nbsp;site.company.com&nbsp;Microsoft&nbsp;Exchange&nbsp;Internet&nbsp;Mail<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connector&nbsp;4.0.xxx.xx<br><br>其中，xxx.xx&nbsp;对&nbsp;RTM&nbsp;是&nbsp;837.3，对&nbsp;SP1&nbsp;是&nbsp;838.14。<br><br>键入以下命令开始进行通讯：<br>HELO&nbsp;test.company.com<br>您应看到如下响应：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;250&nbsp;OK<br><br>键入以下命令来通知&nbsp;IMC&nbsp;邮件源于何处：<br>MAIL&nbsp;FROM:Admin@test.company.com<br>您应得到如下响应：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;250&nbsp;OK&nbsp;-&nbsp;MAIL&nbsp;FROM&nbsp;&lt;[email]Admin@test.company.com[/email]&gt;<br><br>键入以下命令来通知&nbsp;IMC&nbsp;邮件的目标地址（使用一个有效的&nbsp;Microsoft&nbsp;Exchange&nbsp;收件人&nbsp;SMTP&nbsp;地址）。<br>RCPT&nbsp;TO:&lt;[email]User@Site.Domain.Com[/email]&gt;<br>您应看到如下响应：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;250&nbsp;OK&nbsp;-&nbsp;Recipient&nbsp;&lt;[email]User@Site.Domain.Com[/email]&gt;<br><br>键入以下命令以通知&nbsp;IMC&nbsp;您已准备好发送数据：<br>DATA<br>您应看到如下响应：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;354&nbsp;Send&nbsp;data.&nbsp;&nbsp;End&nbsp;with&nbsp;CRLF.CRLF<br><br>键入以下命令以添加主题行：<br>Subject:&nbsp;test&nbsp;message<br><br>然后按两次&nbsp;Enter&nbsp;键。<br><br>该命令看不到任何响应。<br><br>备注：&nbsp;两个&nbsp;Enter&nbsp;命令符合&nbsp;RFC&nbsp;822&nbsp;规则，即&nbsp;822&nbsp;命令后必须跟空行。<br><br><br>键入以下命令来添加邮件正文：<br>This&nbsp;is&nbsp;a&nbsp;test&nbsp;message<br>您将看不到来自该命令的响应。<br><br><br>在紧接着的空行处键入句号，然后按&nbsp;ENTER&nbsp;键。<br><br>您应看到如下响应：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;250&nbsp;OK<br><br>键入以下命令以关闭连接：<br>QUIT<br>您应看到如下响应：<br>221&nbsp;closing&nbsp;connection<br><br>对于上述任一命令，如果您收到&#8220;500&nbsp;Command&nbsp;not&nbsp;recognized&#8221;错误消息，则表明由于语法错误或无效的命令导致&nbsp;IMC&nbsp;无法识别您所键入的内容。<br><br>登录进入您在上述步骤&nbsp;4&nbsp;中选择的邮件收件人的&nbsp;Microsoft&nbsp;Exchange&nbsp;客户邮箱。&nbsp;如果邮箱中有您的测试邮件，说明传入&nbsp;IMC&nbsp;通讯工作正常。<br><br>如果应用程序事件日志显示任何错误消息，或在接收邮件时出现问题，请检查配置或到主机的通讯。</p>
<div class=summary>
<h2>概要</h2>
本文介绍如何&nbsp;telnet&nbsp;到运行简单邮件传输协议&nbsp;(SMTP)&nbsp;服务的计算机上的端口&nbsp;25，以解决&nbsp;SMTP&nbsp;通信问题。默认情况下，SMTP&nbsp;侦听端口&nbsp;25。<br><br>您可以根据您遇到的问题类型选用以下适当的疑难解答步骤。例如，如果您在两台&nbsp;Microsoft&nbsp;Exchange&nbsp;2000&nbsp;Server&nbsp;服务器之间通过&nbsp;SMTP&nbsp;发送邮件时遇到问题，则可以通过在发送服务器上使用&nbsp;Telnet&nbsp;连接到目标服务器上的端口&nbsp;25&nbsp;来测试&nbsp;SMTP&nbsp;连接。或者，如果您在接收来自&nbsp;Internet&nbsp;的&nbsp;SMTP&nbsp;邮件时遇到问题，则可以按照本文中列出的步骤，测试驻留在&nbsp;Internet&nbsp;上但不在您的网络上的主机与您的&nbsp;SMTP&nbsp;服务器的连接。<br></div>
<div class=moreinformation>
<h2>更多信息</h2>
Microsoft&nbsp;产品线中有&nbsp;SMTP&nbsp;的多个不同变体。Microsoft&nbsp;Windows&nbsp;产品线的&nbsp;SMTP&nbsp;服务包含在&nbsp;Internet&nbsp;信息服务&nbsp;(IIS)&nbsp;中，而在&nbsp;Microsoft&nbsp;Windows&nbsp;NT&nbsp;Server&nbsp;4.0&nbsp;中，SMTP&nbsp;服务包含在&nbsp;Option&nbsp;Pack&nbsp;中。在较新版本的&nbsp;Windows&nbsp;中，IIS&nbsp;已被集成到操作系统中，并且您可以使用&#8220;控制面板&#8221;中的&#8220;添加或删除程序&#8221;添加&nbsp;IIS。此外，Exchange&nbsp;2000&nbsp;和&nbsp;Microsoft&nbsp;Exchange&nbsp;Server&nbsp;2003&nbsp;都使用&nbsp;IIS&nbsp;中的现有&nbsp;SMTP&nbsp;服务及其他功能。Microsoft&nbsp;Exchange&nbsp;Server&nbsp;版本&nbsp;4.0、5.0&nbsp;和&nbsp;5.5&nbsp;均包含它们自己的&nbsp;SMTP&nbsp;版本，所采用的形式为&nbsp;Internet&nbsp;Mail&nbsp;Connector&nbsp;(IMC)&nbsp;或&nbsp;Internet&nbsp;Mail&nbsp;Service&nbsp;(IMS)。<br><br><strong>注意</strong>：在&nbsp;Exchange&nbsp;5.0&nbsp;及更高版本中，Internet&nbsp;Mail&nbsp;Connector&nbsp;(IMC)&nbsp;被重命名为&nbsp;Internet&nbsp;Mail&nbsp;Service。<br><br>在启动&nbsp;Telnet&nbsp;会话之前，必须具有要将此测试邮件发送到的目标用户的完整&nbsp;SMTP&nbsp;电子邮件地址。该电子邮件地址必须采用以下格式：&nbsp;
<p class=indent><var>User@Site.Domain.com</var></p>
您也可以具有运行&nbsp;SMTP&nbsp;服务的服务器计算机的完全限定域名&nbsp;(FQDN)&nbsp;或&nbsp;IP&nbsp;地址（例如，10.120.159.1）。如果服务器在您的组织中，您可能已经拥有这些信息。如果服务器是外部服务器，查找这些信息最简单的方法是使用&nbsp;Nslookup.exe&nbsp;以找到包含这些信息的&nbsp;DNS&nbsp;记录。&nbsp;有关&nbsp;NSlookup&nbsp;的其他信息，请单击下面的文章编号，以查看&nbsp;Microsoft&nbsp;知识库中相应的文章：&nbsp;
<p class=indent><a class=KBlink href="http://support.microsoft.com/default.aspx?kbid=200525"><font color=#0000ff><u>200525</u></font></a>&nbsp;使用&nbsp;NSlookup.exe</p>
有关如何获取&nbsp;Internet&nbsp;邮件交换器记录的其他信息，请单击下面的文章编号，以查看&nbsp;Microsoft&nbsp;知识库中相应的文章：&nbsp;
<p class=indent><a class=KBlink href="http://support.microsoft.com/default.aspx?kbid=203204"><font color=#0000ff><u>203204</u></font></a>&nbsp;XFOR：如何获取&nbsp;Internet&nbsp;邮件交换器记录</p>
<br>确保运行&nbsp;SMTP&nbsp;服务的服务器上已启动&nbsp;SMTP。要测试&nbsp;SMTP&nbsp;是否已启动，您可以运行本文中列出的基本测试，并验证您是否会收到来自远程服务器的&nbsp;220&nbsp;消息。这还将验证&nbsp;SMTP&nbsp;是否正在运行。<br><br><strong>注意：</strong>&nbsp;
<ul>
    <li>有些&nbsp;Telnet&nbsp;应用程序要求您打开本地回显功能，以查看键入的命令。要在&nbsp;Microsoft&nbsp;Telnet&nbsp;会话中执行此操作，请在命令提示符处键入&nbsp;<kbd><font face=新宋体>set&nbsp;local_echo</font></kbd>。&nbsp;
    <li>在&nbsp;Microsoft&nbsp;Windows&nbsp;XP&nbsp;中，应键入&nbsp;<kbd><font face=新宋体>set&nbsp;localecho</font></kbd>&nbsp;而不是&nbsp;<kbd><font face=新宋体>set&nbsp;local_echo</font></kbd>。&nbsp; </li>
</ul>
<h3>基本测试</h3>
按照下列步骤操作，以确保主机和远程&nbsp;SMTP&nbsp;服务器能够通信。如果在您键入以下任一命令之后，收到以下错误信息，则说明&nbsp;SMTP&nbsp;服务器因为语法错误或命令错误而无法识别您所键入的内容：<br>
<div class=errormsg>500&nbsp;Command&nbsp;not&nbsp;recognized</div>
检查该命令并再次键入它，或者验证您是否正在与&nbsp;Microsoft&nbsp;SMTP&nbsp;服务器直接通信。<br><br><strong>注意</strong>：Microsoft&nbsp;Telnet&nbsp;不允许您使用&nbsp;Backspace&nbsp;键。如果在键入时出错，必须按&nbsp;Enter&nbsp;键，然后开始键入新的命令。<br><br>在以下步骤中，您要从命令行中运行&nbsp;Telnet。要打开命令行，请单击&#8220;开始&#8221;，单击&#8220;运行&#8221;，在&#8220;打开&#8221;框中键入&nbsp;<kbd><font face=新宋体>cmd</font></kbd>，然后单击&#8220;确定&#8221;。&nbsp;
<ol class=dec>
    <li>您可以通过使用以下格式的&nbsp;Telnet&nbsp;命令来启动&nbsp;Telnet&nbsp;会话：<br><br><strong>注意</strong>：在键入每行内容之后按&nbsp;Enter&nbsp;键。&nbsp;
    <p class=indent><kbd><font face=新宋体>telnet&nbsp;<var>服务器名</var><var>端口号</var></font></kbd></p>
    例如，键入：&nbsp;
    <p class=indent><kbd><font face=新宋体>telnet&nbsp;<var>mail.contoso.com</var>&nbsp;<var>25</var></font></kbd></p>
    <font face="宋体, MS Song"><strong>注意</strong>：您可以将<var>服务器名</var>&nbsp;替换为您要连接到的&nbsp;SMTP&nbsp;服务器的&nbsp;IP&nbsp;地址或&nbsp;FQDN。记住在键入每个命令之后按&nbsp;<strong class=uiterm>Enter</strong>&nbsp;键。<br><br>如果该命令起作用，您将会收到来自&nbsp;SMTP&nbsp;服务器的类似以下内容的消息：</font>&nbsp;
    <p class=indent>?/P&gt;</p>
    <pre class=in_text>220&nbsp;site.contoso.com&nbsp;Microsoft&nbsp;Exchange&nbsp;Internet&nbsp;Mail&nbsp;Connector&nbsp;&lt;IMC&nbsp;的版本号&gt;
    </pre>
    <strong>注意</strong>：由于有许多不同版本的&nbsp;Microsoft&nbsp;SMTP&nbsp;或第三方&nbsp;SMTP&nbsp;服务器，因此您可能会收到来自接收服务器的不同的消息。不过，您肯定会收到包含服务器的&nbsp;FQDN&nbsp;和&nbsp;SMTP&nbsp;的版本的&nbsp;220&nbsp;消息。此外，所有版本的&nbsp;Microsoft&nbsp;SMTP&nbsp;在&nbsp;220&nbsp;消息中都包含&#8220;Microsoft&#8221;一词。&nbsp;
    <li>通过键入以下命令开始通信：&nbsp;
    <p class=indent><kbd><font face=新宋体>EHLO&nbsp;<var>test.com</var></font></kbd></p>
    <strong>注意</strong>：您可以使用&nbsp;HELO&nbsp;命令，但是&nbsp;EHLO&nbsp;是扩展&nbsp;SMTP&nbsp;动词集中的一个动词，SMTP&nbsp;的所有当前&nbsp;Microsoft&nbsp;实现都支持该动词集。除非您认为扩展&nbsp;SMTP&nbsp;动词有问题，否则最好使用&nbsp;EHLO。<br><br>如果该命令成功，您会收到以下消息：&nbsp;
    <p class=indent>?/P&gt;</p>
    <pre class=in_text>250&nbsp;OK
    </pre>
    <li>键入以下命令向接收&nbsp;SMTP&nbsp;服务器通知邮件发件人：&nbsp;
    <p class=indent><kbd><font face=新宋体>MAIL&nbsp;FROM:<var>Admin@test.com</var></font></kbd></p>
    <strong>注意</strong>：该地址可以是您想使用的任何&nbsp;SMTP&nbsp;地址，但是最好考虑以下问题：&nbsp;
    <ol class=alpha>
        <li>有些&nbsp;SMTP&nbsp;邮件系统会基于&nbsp;MAIL&nbsp;FROM:地址筛选邮件，并且会禁止某些&nbsp;IP&nbsp;地址连接到&nbsp;SMTP&nbsp;邮件系统，或者如果连接&nbsp;IP&nbsp;地址与&nbsp;SMTP&nbsp;邮件系统所在的域不匹配，它还会禁止该地址向&nbsp;SMTP&nbsp;邮件系统发送电子邮件。在本例中，该域是&nbsp;<var>test.com</var>。&nbsp;
        <li>如果您在发送邮件时没有使用有效的电子邮件地址，您将无法确定在发送邮件时是否有问题，因为未送达报告&nbsp;(NDR)&nbsp;无法到达无效的&nbsp;IP&nbsp;地址。如果您使用有效的电子邮件地址，您将会收到来自&nbsp;SMTP&nbsp;服务器的以下消息：&nbsp;
        <p class=indent>?/P&gt;</p>
        <pre class=in_text>250&nbsp;OK&nbsp;-&nbsp;MAIL&nbsp;FROM&nbsp;Admin@test.com
        </pre>
        </li>
    </ol>
    <li>键入以下命令向接收&nbsp;SMTP&nbsp;服务器通知邮件的收件人。<br><br><strong>注意</strong>：最好始终使用要发送到的域中的有效收件人&nbsp;SMTP&nbsp;地址。例如，如果您要发送到&nbsp;<var>john@domain.com</var>，必须确保域中存在&nbsp;<var>john@domain.com</var>。否则，您会收到&nbsp;NDR。<br><br>使用您要发送到的人员的&nbsp;SMTP&nbsp;地址键入以下命令：&nbsp;
    <p class=indent><kbd><font face=新宋体>RCPT&nbsp;TO:<var>User@Domain.Com</var></font></kbd></p>
    您会收到以下消息：&nbsp;
    <p class=indent>?/P&gt;</p>
    <pre class=in_text>250&nbsp;OK&nbsp;-&nbsp;Recipient&nbsp;User@&nbsp;Domain.Com
    </pre>
    <li>键入以下命令通知&nbsp;SMTP&nbsp;服务器您已准备好发送数据：&nbsp;
    <p class=indent><kbd><font face=新宋体>DATA</font></kbd></p>
    您会收到以下消息：&nbsp;
    <pre>354&nbsp;Send&nbsp;data.&nbsp;End&nbsp;with&nbsp;CRLF.CRLF
    </pre>
    <li>您现在已可以开始键入邮件的&nbsp;822/2822&nbsp;部分。用户将会在他们的收件箱中看到邮件的这一部分。键入以下命令以添加主题行：&nbsp;
    <p class=indent><kbd><font face=新宋体>Subject:<var>test&nbsp;message</var></font></kbd></p>
    按两次&nbsp;Enter&nbsp;键。此命令不会显示任何信息。<br><br><strong>注意</strong>：按两次&nbsp;Enter&nbsp;键为了与&nbsp;Request&nbsp;for&nbsp;Comments&nbsp;(RFC)&nbsp;822&nbsp;和&nbsp;2822&nbsp;保持一致。它规定&nbsp;822&nbsp;命令后面必须跟一个空行。&nbsp;
    <li>键入以下命令以添加邮件正文：&nbsp;
    <p class=indent><kbd><font face=新宋体>This&nbsp;is&nbsp;a&nbsp;test&nbsp;message&nbsp;you&nbsp;will&nbsp;not&nbsp;see&nbsp;a&nbsp;response&nbsp;from&nbsp;this&nbsp;command.</font></kbd></p>
    <li>在下一个空行中键入英文句点&nbsp;(.)，然后按&nbsp;Enter&nbsp;键。您会收到以下消息：&nbsp;
    <p class=indent>?/P&gt;</p>
    <pre class=in_text>250&nbsp;OK
    </pre>
    <li>键入以下命令关闭连接：&nbsp;
    <p class=indent><kbd><font face=新宋体>QUIT</font></kbd></p>
    您会收到以下消息：&nbsp;
    <p class=indent>?/P&gt;</p>
    <pre class=in_text>221&nbsp;closing&nbsp;connection
    </pre>
    <li>验证收件人是否收到您发送的消息。如果在应用程序事件日志中出现任何错误事件消息，或者接收邮件时出现问题，请检查主机的配置或通信。&nbsp; </li>
</ol>
<h3>高级测试</h3>
除本文前面列出的基本测试步骤外，您还可以使用送达回执对邮件进行双向测试。您可以使用此方法验证&nbsp;SMTP&nbsp;服务器是否可以接受入站连接，并且为发件人生成一个送达回执以测试&nbsp;SMTP&nbsp;服务器的出站连接。<br><br>要为测试邮件请求送达回执，请参见本文&#8220;基本测试&#8221;一节的第&nbsp;4&nbsp;步，以确保提供的信息是可以接收送达回执的有效电子邮件地址。然后在本文&#8220;基本测试&#8221;一节的第&nbsp;5&nbsp;步中，在&nbsp;Telnet&nbsp;会话中键入以下命令</div>
<img src ="http://www.blogjava.net/hua/aggbug/113200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hua/" target="_blank">花</a> 2007-04-24 15:43 <a href="http://www.blogjava.net/hua/archive/2007/04/24/113200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>掌握 Ajax，第 1 部分: Ajax 简介</title><link>http://www.blogjava.net/hua/archive/2006/07/28/60574.html</link><dc:creator>花</dc:creator><author>花</author><pubDate>Fri, 28 Jul 2006 07:13:00 GMT</pubDate><guid>http://www.blogjava.net/hua/archive/2006/07/28/60574.html</guid><wfw:comment>http://www.blogjava.net/hua/comments/60574.html</wfw:comment><comments>http://www.blogjava.net/hua/archive/2006/07/28/60574.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hua/comments/commentRss/60574.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hua/services/trackbacks/60574.html</trackback:ping><description><![CDATA[
		<p>五年前，如果不知道 XML，您就是一只无人重视的丑小鸭。十八个月前，Ruby 成了关注的中心，不知道 Ruby 的程序员只能坐冷板凳了。 今天，如果想跟上最新的技术时尚，那您的目标就是 Ajax。</p>
		<p>但是，Ajax 不<i>仅仅</i> 是一种时尚，它是一种构建网站的强大方法，而且不像学习一种全新的语言那样困难。</p>
		<p>但在详细探讨 Ajax 是什么之前，先让我们花几分钟了解 Ajax <i>做</i> 什么。目前，编写应用程序时有两种基本的选择：</p>
		<ul>
				<li>桌面应用程序 
</li>
				<li>Web 应用程序 </li>
		</ul>
		<p>两者是类似的，桌面应用程序通常以 CD 为介质（有时候可从网站下载）并完全安装到您的计算机上。桌面应用程序可能使用互联网下载更 新，但运行这些应用程序的代码在桌面计算机上。Web 应用程序运行在某处的 Web 服务器上 —— 毫不奇怪，要通过 Web 浏览器访问这种应 用程序。</p>
		<p>不过，比这些应用程序的运行代码放在何处更重要的是，应用程序如何运转以及如何与其进行交互。桌面应用程序一般很快（就在您的计算 机上运行，不用等待互联网连接），具有漂亮的用户界面（通常和操作系统有关）和非凡的动态性。可以单击、选择、输入、打开菜单和子菜 单、到处巡游，基本上不需要等待。</p>
		<p>另一方面，Web 应用程序是最新的潮流，它们提供了在桌面上不能实现的服务（比如 Amazon.com 和 eBay）。但是，伴随着 Web 的强大而 出现的是等待，等待服务器响应，等待屏幕刷新，等待请求返回和生成新的页面。</p>
		<p>显然这样说过于简略了，但基本的概念就是如此。您可能已经猜到，Ajax 尝试建立桌面应用程序的功能和交互性，与不断更新的 Web 应用 程序之间的桥梁。可以使用像桌面应用程序中常见的动态用户界面和漂亮的控件，不过是在 Web 应用程序中。</p>
		<p>还等什么呢？我们来看看 Ajax 如何将笨拙的 Web 界面转化成能迅速响应的 Ajax 应用程序吧。</p>
		<p>
				<a name="N10098">
						<span class="atitle">老技术，新技巧</span>
				</a>
		</p>
		<p>在谈到 Ajax 时，实际上涉及到多种技术，要灵活地运用它必须深入了解这些不同的技术（本系列的头几篇文章将分别讨论这些技术）。好 消息是您可能已经非常熟悉其中的大部分技术，更好的是这些技术都很容易学习，并不像完整的编程语言（如 Java 或 Ruby）那样困难。</p>
		<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N100A3">
																				<b>Ajax 的定义</b>
																		</a>
																		<br />
																		<p>顺便说一下，Ajax 是 Asynchronous JavaScript and XML（以及 DHTML 等）的缩写。这个短语是 Adaptive Path 的 Jesse James Garrett 发明的（请参阅 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#resources">参考资料</a>），按照 Jesse 的解释，这<i>不是</i> 个首字母缩写词。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>下面是 Ajax 应用程序所用到的基本技术：</p>
		<ul>
				<li>HTML 用于建立 Web 表单并确定应用程序其他部分使用的字段。 
</li>
				<li>JavaScript 代码是运行 Ajax 应用程序的核心代码，帮助改进与服务器应用程序的通信。 
</li>
				<li>DHTML 或 Dynamic HTML，用于动态更新表单。我们将使用 <code>div</code>、<code>span</code> 和其他动态 HTML 元素来标记 HTML。 
</li>
				<li>文档对象模型 DOM 用于（通过 JavaScript 代码）处理 HTML 结构和（某些情况下）服务器返回的 XML。 </li>
		</ul>
		<p>我们来进一步分析这些技术的职责。以后的文章中我将深入讨论这些技术，目前只要熟悉这些组件和技术就可以了。对这些代码越熟悉，就 越容易从对这些技术的零散了解转变到真正把握这些技术（同时也真正打开了 Web 应用程序开发的大门）。</p>
		<p>
				<a name="N100D0">
						<span class="smalltitle">XMLHttpRequest 对象</span>
				</a>
		</p>
		<p>要了解的一个对象可能对您来说也是最陌生的，即 <code>XMLHttpRequest</code>。这是一个 JavaScript 对象，创建该对象很简单，如<a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#code1">清单 1</a> 所示。</p>
		<br />
		<a name="code1">
				<b>清单 1. 创建新的 XMLHttpRequest 对象</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">

&lt;script language="javascript" type="text/javascript"&gt;
var xmlHttp = new XMLHttpRequest();
&lt;/script&gt;
</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>下一期文章中将进一步讨论这个对象，现在要知道这是处理所有服务器通信的对象。继续阅读之前，先停下来想一想：通过 <code>XMLHttpRequest</code> 对象与服务器进行对话的是 <i>JavaScript</i> 技术。这不是一般的应用程序流，这恰恰是 Ajax 的强大功能 的来源。</p>
		<p>在一般的 Web 应用程序中，用户填写表单字段并单击 <i>Submit</i> 按钮。然后整个表单发送到服务器，服务器将它转发给处理表单的脚 本（通常是 PHP 或 Java，也可能是 CGI 进程或者类似的东西），脚本执行完成后再发送回全新的页面。该页面可能是带有已经填充某些数据 的新表单的 HTML，也可能是确认页面，或者是具有根据原来表单中输入数据选择的某些选项的页面。当然，在服务器上的脚本或程序处理和返 回新表单时用户必须等待。屏幕变成一片空白，等到服务器返回数据后再重新绘制。这就是交互性差的原因，用户得不到立即反馈，因此感觉 不同于桌面应用程序。</p>
		<p>Ajax 基本上就是把 JavaScript 技术和 <code>XMLHttpRequest</code> 对象放在 Web 表单和服务器<i>之间</i>。当用户填写表单时，数 据发送给一些 JavaScript 代码而<i>不是</i> 直接发送给服务器。相反，JavaScript 代码捕获表单数据并向服务器发送请求。同时用户屏幕 上的表单也不会闪烁、消失或延迟。换句话说，JavaScript 代码在幕后发送请求，用户甚至不知道请求的发出。更好的是，请求是异步发送的 ，就是说 JavaScript 代码（和用户）不用等待服务器的响应。因此用户可以继续输入数据、滚动屏幕和使用应用程序。</p>
		<p>然后，服务器将数据返回 JavaScript 代码（仍然在 Web 表单中），后者决定如何处理这些数据。它可以迅速更新表单数据，让人感觉应 用程序是立即完成的，表单没有提交或刷新而用户得到了新数据。JavaScript 代码甚至可以对收到的数据执行某种计算，再发送另一个请求， 完全不需要用户干预！这就是 <code>XMLHttpRequest</code> 的强大之处。它可以根据需要自行与服务器进行交互，用户甚至可以完全不知道 幕后发生的一切。结果就是类似于桌面应用程序的动态、快速响应、高交互性的体验，但是背后又拥有互联网的全部强大力量。</p>
		<p>
				<a name="N1010E">
						<span class="smalltitle">加入一些 JavaScript</span>
				</a>
		</p>
		<p>得到 <code>XMLHttpRequest</code> 的句柄后，其他的 JavaScript 代码就非常简单了。事实上，我们将使用 JavaScript 代码完成非常 基本的任务：</p>
		<ul>
				<li>获取表单数据：JavaScript 代码很容易从 HTML 表单中抽取数据并发送到服务器。 
</li>
				<li>修改表单上的数据：更新表单也很简单，从设置字段值到迅速替换图像。 
</li>
				<li>解析 HTML 和 XML：使用 JavaScript 代码操纵 DOM（请参阅 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#dom">下一节</a>），处理 HTML 表单服务器返回的 XML 数据的 结构。 </li>
		</ul>
		<p>对于前两点，需要非常熟悉 <code>getElementById()</code> 方法，如 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#code2">清单 2</a> 所示。</p>
		<br />
		<a name="code2">
				<b>清单 2. 用 JavaScript 代码捕获和设置字段值</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">

// Get the value of the "phone" field and stuff it in a variable called phone
var phone = document.getElementById("phone").value;

// Set some values on a form using an array called response
document.getElementById("order").value = response[0];
document.getElementById("address").value = response[1];
</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这里没有特别需要注意的地方，真是好极了！您应该认识到这里并没有非常复杂的东西。只要掌握了 <code>XMLHttpRequest</code>，Ajax 应用程序的其他部分就是如 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#code2">清单 2</a> 所示的简单 JavaScript 代码了，混合有少量的 HTML。同时，还要用一点儿 DOM ，我们就来看看吧。</p>
		<p>
				<a name="dom">
						<span class="smalltitle">以 DOM 结束</span>
				</a>
		</p>
		<p>最后还有 DOM，即文档对象模型。可能对有些读者来说 DOM 有点儿令人生畏，HTML 设计者很少使用它，即使 JavaScript 程序员也不大用 到它，除非要完成某项高端编程任务。大量使用 DOM 的<i>是</i> 复杂的 Java 和 C/C++ 程序，这可能就是 DOM 被认为难以学习的原因。 </p>
		<p>幸运的是，在 JavaScript 技术中使用 DOM 很容易，也非常直观。现在，按照常规也许应该说明如何使用 DOM，或者至少要给出一些示例 代码，但这样做也可能误导您。即使不理会 DOM，仍然能深入地探讨 Ajax，这也是我准备采用的方法。以后的文章将再次讨论 DOM，现在只要 知道可能需要 DOM 就可以了。当需要在 JavaScript 代码和服务器之间传递 XML 和改变 HTML 表单的时候，我们再深入研究 DOM。没有它也 能做一些有趣的工作，因此现在就把 DOM 放到一边吧。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#main">
																				<b>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10158">
						<span class="atitle">获取 Request 对象</span>
				</a>
		</p>
		<p>有了上面的基础知识后，我们来看看一些具体的例子。<code>XMLHttpRequest</code> 是 Ajax 应用程序的核心，而且对很多读者来说可能 还比较陌生，我们就从这里开始吧。从 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#code1">清单 1</a> 可以看出，创建和使用这个对象非常简单，不是吗？等一等。</p>
		<p>还记得几年前的那些讨厌的浏览器战争吗？没有一样东西在不同的浏览器上得到同样的结果。不管您是否相信，这些战争仍然在继续，虽然 规模较小。但令人奇怪的是，<code>XMLHttpRequest</code> 成了这场战争的牺牲品之一。因此获得 <code>XMLHttpRequest</code> 对象可能 需要采用不同的方法。下面我将详细地进行解释。</p>
		<p>
				<a name="N10174">
						<span class="smalltitle">使用 Microsoft 浏览器</span>
				</a>
		</p>
		<p>Microsoft 浏览器 Internet Explorer 使用 MSXML 解析器处理 XML（可以通过 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#resources">参考资料</a> 进一步了解 MSXML ）。因此如果编写的 Ajax 应用程序要和 Internet Explorer 打交道，那么必须用一种特殊的方式创建对象。</p>
		<p>但并不是这么简单。根据 Internet Explorer 中安装的 JavaScript 技术版本不同，MSXML 实际上有两种不同的版本，因此必须对这两种 情况分别编写代码。请参阅 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#code3">清单 3</a>，其中的代码在 Microsoft 浏览器上创建了一个 <code>XMLHttpRequest</code>。 </p>
		<br />
		<a name="code3">
				<b>清单 3. 在 Microsoft 浏览器上创建 XMLHttpRequest 对象</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<pre>
												<code class="section">

var xmlHttp = false;
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}
</code>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>您对这些代码可能还不完全理解，但没有关系。当本系列文章结束的时候，您将对 JavaScript 编程、错误处理、条件编译等有更深的了解 。现在只要牢牢记住其中的两行代码：</p>
		<p>
				<code>xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");</code>
		</p>
		<p>和</p>
		<p>
				<code>xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");</code>。</p>
		<p>这两行代码基本上就是尝试使用一个版本的 MSXML 创建对象，如果失败则使用另一个版本创建该对象。不错吧？如果都不成功，则将 <code>xmlHttp</code> 变量设为 false，告诉您的代码出现了问题。如果出现这种情况，可能是因为安装了非 Microsoft 浏览器，需要使用 不同的代码。</p>
		<p>
				<a name="N101AE">
						<span class="smalltitle">处理 Mozilla 和非 Microsoft 浏览器</span>
				</a>
		</p>
		<p>如果选择的浏览器不是 Internet Explorer，或者为非 Microsoft 浏览器编写代码，就需要使用不同的代码。事实上就是 <a href="http://gocom.primeton.com/modules/techresource/article536.htm?utm_campaign=searchengine&amp;utm_source=baidu&amp;utm_medium=jjpm&amp;utm_term=AJAX#code1">清单 1</a> 所示的一行简单代码：</p>
<img src ="http://www.blogjava.net/hua/aggbug/60574.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hua/" target="_blank">花</a> 2006-07-28 15:13 <a href="http://www.blogjava.net/hua/archive/2006/07/28/60574.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ajax简介</title><link>http://www.blogjava.net/hua/archive/2006/07/28/60573.html</link><dc:creator>花</dc:creator><author>花</author><pubDate>Fri, 28 Jul 2006 07:09:00 GMT</pubDate><guid>http://www.blogjava.net/hua/archive/2006/07/28/60573.html</guid><wfw:comment>http://www.blogjava.net/hua/comments/60573.html</wfw:comment><comments>http://www.blogjava.net/hua/archive/2006/07/28/60573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hua/comments/commentRss/60573.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hua/services/trackbacks/60573.html</trackback:ping><description><![CDATA[作为J2EE开发人员，我们似乎经常关注“后端机制（backend mechanics）”。我们通常会忘记，J2EE的主要成功之处在Web应用程序方面；许多原因使得人们喜欢利用Web开发应用程序，但主要还是因为其易于部署的特点允许站点以尽可能低的成本拥有上百万的用户。遗憾的是，在过去几年中，我们在后端投入了太多的时间，而在使我们的Web用户界面对用户自然和响应灵敏方面却投入不足。
<p>　　本文介绍一种方法，Ajax，使用它可以构建更为动态和响应更灵敏的Web应用程序。该方法的关键在于对浏览器端的JavaScript、DHTML和与服务器异步通信的组合。本文也演示了启用这种方法是多么简单：利用一个Ajax框架（指DWR）构造一个应用程序，它直接从浏览器与后端服务进行通信。如果使用得当，这种强大的力量可以使应用程序更加自然和响应灵敏，从而提升用户的浏览体验。</p><p>　　该应用程序中所使用的示例代码已打包为单独的WAR文件，可供下载。</p><p><strong>简介</strong></p><p>　　术语Ajax用来描述一组技术，它使浏览器可以为用户提供更为自然的浏览体验。在Ajax之前，Web站点强制用户进入提交/等待/重新显示范例，用户的动作总是与服务器的“思考时间”同步。Ajax提供与服务器异步通信的能力，从而使用户从请求/响应的循环中解脱出来。借助于Ajax，可以在用户单击按钮时，使用JavaScript和DHTML立即更新UI，并向服务器发出异步请求，以执行更新或查询数据库。当请求返回时，就可以使用JavaScript和CSS来相应地更新UI，而不是刷新整个页面。最重要的是，用户甚至不知道浏览器正在与服务器通信：Web站点看起来是即时响应的。</p><p>　　虽然Ajax所需的基础架构已经出现了一段时间，但直到最近异步请求的真正威力才得到利用。能够拥有一个响应极其灵敏的Web站点确实激动人心，因为它最终允许开发人员和设计人员使用标准的HTML/CSS/JavaScript堆栈创建“桌面风格的（desktop-like）”可用性。</p><p>　　通常，在J2EE中，开发人员过于关注服务和持久性层的开发，以至于用户界面的可用性已经落后。在一个典型的J2EE开发周期中，常常会听到这样的话，“我们没有可投入UI的时间”或“不能用HTML实现”。但是，以下Web站点证明，这些理由再也站不住脚了：</p><ul><li><a href="http://backpackit.com/" target="_blank">BackPack</a></li><li><a href="http://www.google.com/webhp?complete=1&amp;hl=en" target="_blank">Google Suggest</a></li><li><a href="http://maps.google.com/" target="_blank">Google Maps</a></li><li><a href="http://www.palmsphere.com/" target="_blank">PalmSphere</a></li></ul><p>　　所有这些Web站点都告诉我们，Web应用程序不必完全依赖于从服务器重新载入页面来向用户呈现更改。一切似乎就在瞬间发生。简而言之，在涉及到用户界面的响应灵敏度时，基准设得更高了。</p><p><strong>定义Ajax</strong></p><p>　　Adaptive Path公司的Jesse James Garrett这样<a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" target="_blank">定义Ajax</a>：</p><p>　　Ajax不是一种技术。实际上，它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含：</p><ul><li>基于<a href="http://www.w3.org/TR/xhtml1/" target="_blank">XHTML</a>和<a href="http://www.w3.org/Style/CSS/" target="_blank">CSS</a>标准的表示； 
</li><li>使用<a href="http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/introduction.html" target="_blank">Document Object Model</a>进行动态显示和交互； 
</li><li>使用XMLHttpRequest与服务器进行异步通信； 
</li><li>使用JavaScript绑定一切。 </li></ul><p>　　这非常好，但为什么要以Ajax命名呢？其实术语Ajax是由Jesse James Garrett创造的，他说它是“Asynchronous JavaScript + XML的简写”。</p><p><strong>Ajax的工作原理</strong></p><p>　　Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入，它是一种支持异步请求的技术。简而言之，XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应，而不阻塞用户。</p><p>　　在创建Web站点时，在客户端执行屏幕更新为用户提供了很大的灵活性。下面是使用Ajax可以完成的功能：</p><ul><li>动态更新购物车的物品总数，无需用户单击Update并等待服务器重新发送整个页面。 
</li><li>提升站点的性能，这是通过减少从服务器下载的数据量而实现的。例如，在Amazon的购物车页面，当更新篮子中的一项物品的数量时，会重新载入整个页面，这必须下载32K的数据。如果使用Ajax计算新的总量，服务器只会返回新的总量值，因此所需的带宽仅为原来的百分之一。 
</li><li>消除了每次用户输入时的页面刷新。例如，在Ajax中，如果用户在分页列表上单击Next，则服务器数据只刷新列表而不是整个页面。 
</li><li>直接编辑表格数据，而不是要求用户导航到新的页面来编辑数据。对于Ajax，当用户单击Edit时，可以将静态表格刷新为内容可编辑的表格。用户单击Done之后，就可以发出一个Ajax请求来更新服务器，并刷新表格，使其包含静态、只读的数据。 </li></ul><p>　　一切皆有可能！但愿它能够激发您开始开发自己的基于Ajax的站点。然而，在开始之前，让我们介绍一个现有的Web站点，它遵循传统的提交/等待/重新显示的范例，我们还将讨论Ajax如何提升用户体验。</p><p><strong>Ajax可用于那些场景？——一个例子：MSN Money页面</strong></p><p>　　前几天，在浏览MSN Money页面的时候，有一篇<a href="http://moneycentral.msn.com/content/Investing/Realestate/P63633.asp" target="_blank">关于房地产投资的文章</a>引起了我的好奇心。我决定使用站点的“Rate this article”（评价本文）功能，鼓励其他的用户花一点时间来阅读这篇文章。在我单击vote按钮并等待了一会儿之后，整个页面被刷新，在原来投票问题所在的地方出现了一个漂亮的感谢画面。</p><p><img height="63" src="http://dev2dev.bea.com.cn/images/051101/0511010101.jpg" width="303" /></p><p>　　而Ajax能够使用户的体验更加愉快，它可以提供响应更加灵敏的UI，并消除页面刷新所带来的闪烁。目前，由于要刷新整个页面，需要传送大量的数据，因为必须重新发送整个页面。如果使用Ajax，服务器可以返回一个包含了感谢信息的500字节的消息，而不是发送26,813字节的消息来刷新整个页面。即使使用的是高速Internet，传送26K和1/2K的差别也非常大。同样重要的是，只需要刷新与投票相关的一小节，而不是刷新整个屏幕。</p><p>　　让我们利用Ajax实现自己的基本投票系统。</p><p><strong>原始的Ajax：直接使用XmlHttpRequest</strong></p><p>　　如上所述，Ajax的核心是JavaScript对象XmlHttpRequest。下面的示例文章评价系统将带您熟悉Ajax的底层基本知识：<a href="http://tearesolutions.com/ajax-demo/raw-ajax.html" target="_blank">http://tearesolutions.com/ajax-demo/raw-ajax.html</a>。注：如果您已经在本地WebLogic容器中安装了<a href="http://dev2dev.bea.com/2005/08/ajax-demo.war">ajax-demo.war</a>，可以导航到<a href="http://localhost:7001/ajax-demo/raw-ajax.html" target="_blank">http://localhost:7001/ajax-demo/raw-ajax.html</a>，</p><p>　　浏览应用程序，参与投票，并亲眼看它如何运转。熟悉了该应用程序之后，继续阅读，进一步了解其工作原理细节。</p>　　首先，您拥有一些简单的定位点标记，它连接到一个JavaScriptcastVote(rank)函数。 <pre class="code">function castVote(rank) {
  var url = "/ajax-demo/static-article-ranking.html";
  var callback = processAjaxResponse;
  executeXhr(callback, url);
}
</pre><p>　　该函数为您想要与之通信的服务器资源创建一个URL并调用内部函数executeXhr，提供一个回调JavaScript函数，一旦服务器响应可用，该函数就被执行。由于我希望它运行在一个简单的Apache环境中，“cast vote URL”只是一个简单的HTML页面。在实际情况中，被调用的URL将记录票数并动态地呈现包含投票总数的响应。</p>　　下一步是发出一个XmlHttpRequest请求： <pre class="code">function executeXhr(callback, url) {
  // branch for native XMLHttpRequest object
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
    req.onreadystatechange = callback;
    req.open("GET", url, true);
    req.send(null);
  } // branch for IE/Windows ActiveX version
  else if (window.ActiveXObject) {
    req = new ActiveXObject("Microsoft.XMLHTTP");
    if (req) {
      req.onreadystatechange = callback;
      req.open("GET", url, true);
      req.send();
    }
  }
}

</pre><p>　　如您所见，执行一个XmlHttpRequest并不简单，但非常直观。和平常一样，在JavaScript领域，大部分的工作量都花在确保浏览器兼容方面。在这种情况下，首先要确定XmlHttpRequest是否可用。如果不能用，很可能要使用Internet Explorer，这样就要使用所提供的ActiveX实现。</p><p>executeXhr()方法中最关键的部分是这两行： </p><pre class="code">req.onreadystatechange = callback;
req.open("GET", url, true);
</pre><p>　　第一行定义了JavaScript回调函数，您希望一旦响应就绪它就自动执行，而req.open()方法中所指定的“true”标志说明您想要异步执行该请求。</p>　　一旦服务器处理完XmlHttpRequest并返回给浏览器，使用req.onreadystatechange指派所设置的回调方法将被自动调用。 <pre class="code">function processAjaxResponse() {
  // only if req shows "loaded"
  if (req.readyState == 4) {
    // only if "OK"
    if (req.status == 200) {
      502 502'votes').innerHTML = req.responseText;
    } else {
      alert("There was a problem retrieving the XML data:
" +
      req.statusText);
    }
  }
} 
</pre><p>　　该代码相当简洁，并且使用了几个幻数，这使得难以一下子看出发生了什么。为了弄清楚这一点，下面的表格（引用自<a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html" target="_blank">http://developer.apple.com/internet/webcontent/xmlhttpreq.html</a>）列举了常用的XmlHttpRequest对象属性。</p><table cellspacing="1" cellpadding="0" width="80%" bgcolor="#cccccc" border="0"><tbody><tr bgcolor="#ffffff"><td height="22"><p><strong>属性</strong></p></td><td><p><strong>描述</strong></p></td></tr><tr bgcolor="#ffffff"><td valign="top" height="22"><p>onreadystatechange</p></td><td valign="top"><p>每次状态改变所触发事件的事件处理程序</p></td></tr><tr bgcolor="#ffffff"><td valign="top" height="22"><p>readyState</p></td><td valign="top"><p>对象状态值： 
</p><ul><li>0 = 未初始化（uninitialized） 
</li><li>1 = 正在加载（loading） 
</li><li>2 = 加载完毕（loaded） 
</li><li>3 = 交互（interactive） 
</li><li>4 = 完成（complete） </li></ul></td></tr><tr bgcolor="#ffffff"><td valign="top" height="22"><p>responseText</p></td><td valign="top"><p>从服务器进程返回的数据的字符串形式</p></td></tr><tr bgcolor="#ffffff"><td valign="top" height="22"><p>responseXML</p></td><td valign="top"><p>从服务器进程返回的DOM兼容的文档数据对象</p></td></tr><tr bgcolor="#ffffff"><td valign="top" height="22"><p>status</p></td><td valign="top"><p>从服务器返回的数字代码，比如404（未找到）或200（就绪）</p></td></tr><tr bgcolor="#ffffff"><td valign="top" height="22"><p>statusText</p></td><td valign="top"><p>伴随状态码的字符串信息</p></td></tr></tbody></table><p>　　现在processVoteResponse()函数开始显示出其意义了。它首先检查XmlHttpRequest的整体状态以保证它已经完成（readyStatus == 4），然后根据服务器的设定询问请求状态。如果一切正常（status == 200）,就使用innerHTML属性重写DOM的“votes”节点的内容。</p><p>　　既然您亲眼看到了XmlHttpRequest对象是如何工作的，就让我们利用一个旨在简化JavaScript与Java应用程序之间的异步通信的框架来对具体的细节进行抽象。</p><p><strong>Ajax: DWR方式</strong></p><p>　　按照与文章评价系统相同的流程，我们将使用Direct Web Remoting（DWR）框架实现同样的功能。</p><p>　　假定文章和投票结果存储在一个数据库中，使用某种对象/关系映射技术来完成抽取工作。为了部署起来尽可能地简单，我们不会使用数据库进行持久性存储。此外，为使应用程序尽可能通用，也不使用Web框架。相反，应用程序将从一个静态HTML文件开始，可以认为它由服务器动态地呈现。除了这些简化措施，应用程序还应该使用Spring Framework关联一切，以便轻松看出如何在一个“真实的”应用程序中使用DWR。</p><p>　　现在应该下载示例应用程序并熟悉它。该应用程序被压缩为标准的WAR文件，因此您可以把它放置到任何一个Web容器中——无需进行配置。部署完毕之后，就可以导航到<a href="http://localhost:7001/ajax-demo/dwr-ajax.html" target="_blank">http://localhost:7001/ajax_demo/dwr-ajax.html</a>来运行程序。</p><p>　　可以查看<a href="http://dev2dev.bea.com/2005/08/source.html" target="_blank">HTML 源代码</a>，了解它如何工作。给人印象最深的是，代码如此简单——所有与服务器的交互都隐藏在JavaScript对象ajaxSampleSvc的后面。更加令人惊讶的是，ajaxSampleSvc服务不是由手工编写而是完全自动生成的！让我们继续，看看这是如何做到的。</p><p><strong>引入DWR</strong></p><p>　　如同在“原始的Ajax”一节所演示的那样，直接使用XmlHttpRequest创建异步请求非常麻烦。不仅JavaScript代码冗长，而且必须考虑服务器端为定位Ajax请求到适当的服务所需做的工作，并将结果封送到浏览器。</p><p>　　设计DWR的目的是要处理将Web页面安装到后端服务上所需的所有信息管道。它是一个Java框架，可以很轻松地将它插入到Web应用程序中，以便JavaScript代码可以调用服务器上的服务。它甚至直接与Spring Framework集成，从而允许用户直接向Web客户机公开bean。</p><p>　　DWR真正的巧妙之处是，在用户配置了要向客户机公开的服务之后，它使用反射来生成JavaScript对象，以便Web页面能够使用这些对象来访问该服务。然后Web页面只需接合到生成的JavaScript对象，就像它们是直接使用服务一样；DWR无缝地处理所有有关Ajax和请求定位的琐碎细节。</p><p>　　让我们仔细分析一下示例代码，弄清它是如何工作的。</p><p><strong>应用程序细节：DWR分析</strong></p><p>　　关于应用程序，首先要注意的是，它是一个标准的Java应用程序，使用分层架构（Layered Architecture）设计模式。使用DWR通过JavaScript公开一些服务并不影响您的设计。 </p><p><img height="344" src="http://dev2dev.bea.com.cn/images/051101/0511010102.jpg" width="209" /></p><p>　　下面是一个简单的Java服务，我们将使用DWR框架直接将其向JavaScript代码公开：</p><pre class="code">package com.tearesolutions.service;

public interface AjaxSampleSvc { 
  Article castVote(int rank);
}
</pre><p>　　这是一个被简化到几乎不可能的程度的例子，其中只有一篇文章可以投票。该服务由Spring管理，它使用的bean名是ajaxSampleSvc，它的持久性需求则依赖于ArticleDao。详情请参见applicationContext.xml。</p><p>　　为了把该服务公开为JavaScript对象，需要配置DWR，添加dwr.xml文件到WEB-INF目录下： </p><pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE dwr PUBLIC
 "-//GetAhead Limited//DTD Direct Web Remoting 0.4//EN"
 "http://www.getahead.ltd.uk/dwr/dwr.dtd"&gt;
	
&lt;dwr&gt;
 &lt;allow&gt;
  &lt;create creator="spring" javascript="ajaxSampleSvc"&gt;
   &lt;param name="beanName" value="ajaxSampleSvc" /&gt;
  &lt;/create&gt;
  &lt;convert converter="bean" match="com.tearesolutions.model.Article"/&gt;
  &lt;exclude method="toString"/&gt;
  &lt;exclude method="setArticleDao"/&gt;
 &lt;/allow&gt;
&lt;/dwr&gt;
</pre><p>　　dwr.xml文件告诉DWR哪些服务是要直接向JavaScript代码公开的。注意，已经要求公开Spring bean ajaxSampleSvc。DWR将自动找到由应用程序设置的SpringApplicationContext。为此，必须使用标准的servlet过滤器ContextLoaderListener来初始化Spring ApplicationContext。</p>　　DWR被设置为一个servlet，所以把它的定义添加到web.xml： <pre class="code">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD 
 Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;

&lt;web-app&gt;
 &lt;display-name&gt;Ajax Examples&lt;/display-name&gt;

 &lt;listener&gt;
  &lt;listener-class&gt;
      org.springframework.web.context.ContextLoaderListener
  &lt;/listener-class&gt;
 &lt;/listener&gt;
	
 &lt;servlet&gt;
  &lt;servlet-name&gt;ajax_sample&lt;/servlet-name&gt;
  &lt;servlet-class&gt;com.tearesolutions.web.AjaxSampleServlet&lt;/servlet-class&gt;
  &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
 &lt;/servlet&gt;

 &lt;servlet&gt;
  &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;
  &lt;display-name&gt;DWR Servlet&lt;/display-name&gt;
  &lt;description&gt;Direct Web Remoter Servlet&lt;/description&gt;
  &lt;servlet-class&gt;uk.ltd.getahead.dwr.DWRServlet&lt;/servlet-class&gt;
  &lt;init-param&gt;
   &lt;param-name&gt;debug&lt;/param-name&gt;
   &lt;param-value&gt;true&lt;/param-value&gt;
  &lt;/init-param&gt;
 &lt;/servlet&gt;

 &lt;servlet-mapping&gt;
  &lt;servlet-name&gt;ajax_sample&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/ajax_sample&lt;/url-pattern&gt;
 &lt;/servlet-mapping&gt;

 &lt;servlet-mapping&gt;
  &lt;servlet-name&gt;dwr-invoker&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/dwr/*&lt;/url-pattern&gt;
 &lt;/servlet-mapping&gt;
&lt;/web-app&gt;
</pre><p>　　做完这些之后，可以加载<a href="http://localhost:7001/ajax-demo/dwr" target="_blank">http://localhost:7001/ajax-demo/dwr</a>，看看哪些服务可用。结果如下：</p><p><img height="102" src="http://dev2dev.bea.com.cn/images/051101/0511010103.jpg" width="305" /></p><p>图3. 可用的服务</p>　　单击ajaxSampleSvc链接，查看有关如何在HTML页面内直接使用服务的示例实现。其中包含的两个JavaScript文件完成了大部分的功能： <pre class="code">&lt;script type='text/javascript' 
   src='/ajax-demo/dwr/interface/ajaxSampleSvc.js'&gt;&lt;/script&gt;
&lt;script type='text/javascript' 
   src='/ajax-demo/dwr/engine.js'&gt;&lt;/script&gt;
</pre><p>ajaxSampleSvc.js是动态生成的：</p><pre class="code">function ajaxSampleSvc() { }

ajaxSampleSvc.castVote = function(callback, p0)
{ 
  DWREngine._execute(callback, '/ajax-demo/dwr', 
 'ajaxSampleSvc', 'castVote', p0);
}
</pre><p>　　现在可以使用JavaScript对象ajaxSampleSvc替换所有的XmlHttpRequest代码，从而重构raw-ajax.html文件。可以在dwr-ajax.html文件中看到改动的结果；下面是新的JavaScript函数：</p><pre class="code">function castVote(rank) {
  ajaxSampleSvc.castVote(processResponse, rank);
}
function processResponse(data) {
 var voteText = "<p><strong>Thanks for Voting!</strong></p>"
    + "<p>Current ranking: " + data.voteAverage 
    + " out of 5</p>" 
    + "<p>Number of votes placed: " 
    + data.numberOfVotes + "</p>";
 502 502'votes').innerHTML = voteText;       
}
</pre><p>　　惊人地简单，不是吗？由ajaxSampleSvc对象返回的Article域对象序列化为一个JavaScript对象，允许在它上面调用诸如numberOfVotes()和voteAverage()之类的方法。在动态生成并插入到DIV元素“votes”中的HTML代码内使用这些数据。</p><p><strong>下一步工作</strong></p><p>　　　在后续文章中，我将继续有关Ajax的话题，涉及下面这些方面：</p><ul><li>Ajax最佳实践 </li></ul><p>　　像许多技术一样，Ajax是一把双刃剑。对于一些用例，其应用程序其实没有必要使用Ajax，使用了反而有损可用性。我将介绍一些不适合使用的模式，突出说明Ajax的一些消极方面，并展示一些有助于缓和这些消极方面的机制。例如，对<a href="http://www.netflix.com/BrowseSelection">Netflix电影浏览器</a>来说，Ajax是合适的解决方案吗？或者，如何提示用户确实出了一些问题，而再次单击按钮也无济于事？</p><ul><li>管理跨请求的状态 </li></ul><p>　　在使用Ajax时，最初的文档DOM会发生一些变化，并且有大量的页面状态信息存储在客户端变量中。当用户跟踪一个链接到应用程序中的另一个页面时，状态就丢失了。当用户按照惯例单击Back按钮时，呈现给他们的是缓存中的初始页面。这会使用户感到非常迷惑！</p><ul><li>调试技巧 </li></ul><p>　　使用JavaScript在客户端执行更多的工作时，如果事情不按预期方式进行，就需要一些调试工具来帮助弄清出现了什么问题。</p><p><strong>结束语</strong></p><p>　　本文介绍了Ajax方法，并展示了如何使用它来创建一个动态且响应灵敏的Web应用程序。通过使用DWR框架，可以轻松地把Ajax融合到站点中，而无需担心所有必须执行的实际管道工作。</p><p>　　特别感谢Getahead IT咨询公司的Joe Walker和他的团队开发出DWR这样神奇的工具。感谢你们与世界共享它！</p><p><strong>下载</strong></p><p>　　本文中演示的应用程序源代码可供下载：<a href="http://dev2dev.bea.com/2005/08/ajax-demo.war" target="_blank">ajax-demo.war</a>（1.52 MB）。</p><p><strong>参考资料</strong></p><ul><li><a href="http://www.getahead.ltd.uk/dwr" target="_blank">http://www.getahead.ltd.uk/dwr</a>——Getahead IT咨询公司。 
</li><li>Jesse James Garrett所撰写的“<a href="http://www.adaptivepath.com/publications/essays/archives/000385.php" target="_blank">Ajax: A New Approach to Web Applications</a>”（Adaptive Path，2005年二月）。 
</li><li>“<a href="http://developer.apple.com/internet/webcontent/xmlhttpreq.html" target="_blank">Dynamic HTML and XML: The XMLHttpRequest Object</a>”（Apple Developer Connection）。 </li></ul><p><strong>原文出处</strong></p><p>An Introduction To Ajax</p><p><a href="http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html" target="_blank">http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html</a></p><!--文章其他信息--><img src ="http://www.blogjava.net/hua/aggbug/60573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hua/" target="_blank">花</a> 2006-07-28 15:09 <a href="http://www.blogjava.net/hua/archive/2006/07/28/60573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>