星期一, 九月 25, 2006

Ajax简介

Ajax简介

时间:2005-11-01
作者:David Teare
浏览次数:
本文关键字:ajax, dhtml, dwr, javascript

  作为J2EE开发人员,我们似乎经常关注“后端机制(backend mechanics)”。我们通常会忘记,J2EE的主要成功之处在Web应用程序方面;许多原因使得人们喜欢利用Web开发应用程序,但主要还是因为其 易于部署的特点允许站点以尽可能低的成本拥有上百万的用户。遗憾的是,在过去几年中,我们在后端投入了太多的时间,而在使我们的Web用户界面对用户自然 和响应灵敏方面却投入不足。

  本文介绍一种方法,Ajax,使用它可以构建更为动态和响应更灵敏的Web应用程序。该方法的关键在于对浏览器端的JavaScript、 DHTML和与服务器异步通信的组合。本文也演示了启用这种方法是多么简单:利用一个Ajax框架(指DWR)构造一个应用程序,它直接从浏览器与后端服 务进行通信。如果使用得当,这种强大的力量可以使应用程序更加自然和响应灵敏,从而提升用户的浏览体验。

  该应用程序中所使用的示例代码已打包为单独的WAR文件,可供下载。

简介

  术语Ajax用来描述一组技术,它使浏览器可以为用户提供更为自然的浏览体验。在Ajax之前,Web站点强制用户进入提交/等待/重新显示范 例,用户的动作总是与服务器的“思考时间”同步。Ajax提供与服务器异步通信的能力,从而使用户从请求/响应的循环中解脱出来。借助于Ajax,可以在 用户单击按钮时,使用JavaScript和DHTML立即更新UI,并向服务器发出异步请求,以执行更新或查询数据库。当请求返回时,就可以使用 JavaScript和CSS来相应地更新UI,而不是刷新整个页面。最重要的是,用户甚至不知道浏览器正在与服务器通信:Web站点看起来是即时响应 的。

  虽然Ajax所需的基础架构已经出现了一段时间,但直到最近异步请求的真正威力才得到利用。能够拥有一个响应极其灵敏的Web站点确实激动人 心,因为它最终允许开发人员和设计人员使用标准的HTML/CSS/JavaScript堆栈创建“桌面风格的(desktop-like)”可用性。

  通常,在J2EE中,开发人员过于关注服务和持久性层的开发,以至于用户界面的可用性已经落后。在一个典型的J2EE开发周期中,常常会听到这样的话,“我们没有可投入UI的时间”或“不能用HTML实现”。但是,以下Web站点证明,这些理由再也站不住脚了:

  所有这些Web站点都告诉我们,Web应用程序不必完全依赖于从服务器重新载入页面来向用户呈现更改。一切似乎就在瞬间发生。简而言之,在涉及到用户界面的响应灵敏度时,基准设得更高了。

定义Ajax

  Adaptive Path公司的Jesse James Garrett这样定义Ajax

  Ajax不是一种技术。实际上,它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含:

  • 基于XHTMLCSS标准的表示;
  • 使用Document Object Model进行动态显示和交互;
  • 使用XMLHttpRequest与服务器进行异步通信;
  • 使用JavaScript绑定一切。

  这非常好,但为什么要以Ajax命名呢?其实术语Ajax是由Jesse James Garrett创造的,他说它是“Asynchronous JavaScript + XML的简写”。

Ajax的工作原理

  Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不 阻塞用户。

  在创建Web站点时,在客户端执行屏幕更新为用户提供了很大的灵活性。下面是使用Ajax可以完成的功能:

  • 动态更新购物车的物品总数,无需用户单击Update并等待服务器重新发送整个页面。
  • 提升站点的性 能,这是通过减少从服务器下载的数据量而实现的。例如,在Amazon的购物车页面,当更新篮子中的一项物品的数量时,会重新载入整个页面,这必须下载 32K的数据。如果使用Ajax计算新的总量,服务器只会返回新的总量值,因此所需的带宽仅为原来的百分之一。
  • 消除了每次用户输入时的页面刷新。例如,在Ajax中,如果用户在分页列表上单击Next,则服务器数据只刷新列表而不是整个页面。
  • 直接编辑表格数据,而不是要求用户导航到新的页面来编辑数据。对于Ajax,当用户单击Edit时,可以将静态表格刷新为内容可编辑的表格。用户单击Done之后,就可以发出一个Ajax请求来更新服务器,并刷新表格,使其包含静态、只读的数据。

  一切皆有可能!但愿它能够激发您开始开发自己的基于Ajax的站点。然而,在开始之前,让我们介绍一个现有的Web站点,它遵循传统的提交/等待/重新显示的范例,我们还将讨论Ajax如何提升用户体验。

Ajax可用于那些场景?——一个例子:MSN Money页面

  前几天,在浏览MSN Money页面的时候,有一篇关于房地产投资的文章引起了我的好奇心。我决定使用站点的“Rate this article”(评价本文)功能,鼓励其他的用户花一点时间来阅读这篇文章。在我单击vote按钮并等待了一会儿之后,整个页面被刷新,在原来投票问题所在的地方出现了一个漂亮的感谢画面。

  而Ajax能够使用户的体验更加愉快,它可以提供响应更加灵敏的UI,并消除页面刷新所带来的闪烁。目前,由于要刷新整个页面,需要传送大量的 数据,因为必须重新发送整个页面。如果使用Ajax,服务器可以返回一个包含了感谢信息的500字节的消息,而不是发送26,813字节的消息来刷新整个 页面。即使使用的是高速Internet,传送26K和1/2K的差别也非常大。同样重要的是,只需要刷新与投票相关的一小节,而不是刷新整个屏幕。

  让我们利用Ajax实现自己的基本投票系统。

原始的Ajax:直接使用XmlHttpRequest

  如上所述,Ajax的核心是JavaScript对象XmlHttpRequest。下面的示例文章评价系统将带您熟悉Ajax的底层基本知识:http://tearesolutions.com/ajax-demo/raw-ajax.html。注:如果您已经在本地WebLogic容器中安装了ajax-demo.war,可以导航到http://localhost:7001/ajax-demo/raw-ajax.html

  浏览应用程序,参与投票,并亲眼看它如何运转。熟悉了该应用程序之后,继续阅读,进一步了解其工作原理细节。

  首先,您拥有一些简单的定位点标记,它连接到一个JavaScriptcastVote(rank)函数。
function castVote(rank) {
var url = "/ajax-demo/static-article-ranking.html";
var callback = processAjaxResponse;
executeXhr(callback, url);
}

  该函数为您想要与之通信的服务器资源创建一个URL并调用内部函数executeXhr,提供一个回调JavaScript函数,一旦服务器响 应可用,该函数就被执行。由于我希望它运行在一个简单的Apache环境中,“cast vote URL”只是一个简单的HTML页面。在实际情况中,被调用的URL将记录票数并动态地呈现包含投票总数的响应。

  下一步是发出一个XmlHttpRequest请求:
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();
}
}
}

  如您所见,执行一个XmlHttpRequest并不简单,但非常直观。和平常一样,在JavaScript领域,大部分的工作量都花在确保浏 览器兼容方面。在这种情况下,首先要确定XmlHttpRequest是否可用。如果不能用,很可能要使用Internet Explorer,这样就要使用所提供的ActiveX实现。

executeXhr()方法中最关键的部分是这两行:

req.onreadystatechange = callback;
req.open("GET", url, true);

  第一行定义了JavaScript回调函数,您希望一旦响应就绪它就自动执行,而req.open()方法中所指定的“true”标志说明您想要异步执行该请求。

  一旦服务器处理完XmlHttpRequest并返回给浏览器,使用req.onreadystatechange指派所设置的回调方法将被自动调用。
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);
}
}
}

  该代码相当简洁,并且使用了几个幻数,这使得难以一下子看出发生了什么。为了弄清楚这一点,下面的表格(引用自http://developer.apple.com/internet/webcontent/xmlhttpreq.html)列举了常用的XmlHttpRequest对象属性。

属性

描述

onreadystatechange

每次状态改变所触发事件的事件处理程序

readyState

对象状态值:

  • 0 = 未初始化(uninitialized)
  • 1 = 正在加载(loading)
  • 2 = 加载完毕(loaded)
  • 3 = 交互(interactive)
  • 4 = 完成(complete)

responseText

从服务器进程返回的数据的字符串形式

responseXML

从服务器进程返回的DOM兼容的文档数据对象

status

从服务器返回的数字代码,比如404(未找到)或200(就绪)

statusText

伴随状态码的字符串信息

  现在processVoteResponse()函数开始显示出其意义了。它首先检查XmlHttpRequest的整体状态以保证它已经完成 (readyStatus == 4),然后根据服务器的设定询问请求状态。如果一切正常(status == 200),就使用innerHTML属性重写DOM的“votes”节点的内容。

  既然您亲眼看到了XmlHttpRequest对象是如何工作的,就让我们利用一个旨在简化JavaScript与Java应用程序之间的异步通信的框架来对具体的细节进行抽象。

Ajax: DWR方式

  按照与文章评价系统相同的流程,我们将使用Direct Web Remoting(DWR)框架实现同样的功能。

  假定文章和投票结果存储在一个数据库中,使用某种对象/关系映射技术来完成抽取工作。为了部署起来尽可能地简单,我们不会使用数据库进行持久性 存储。此外,为使应用程序尽可能通用,也不使用Web框架。相反,应用程序将从一个静态HTML文件开始,可以认为它由服务器动态地呈现。除了这些简化措 施,应用程序还应该使用Spring Framework关联一切,以便轻松看出如何在一个“真实的”应用程序中使用DWR。

  现在应该下载示例应用程序并熟悉它。该应用程序被压缩为标准的WAR文件,因此您可以把它放置到任何一个Web容器中——无需进行配置。部署完毕之后,就可以导航到http://localhost:7001/ajax_demo/dwr-ajax.html来运行程序。

  可以查看HTML 源代码,了解它如何工作。给人印象最深的是,代码如此简单——所有与服务器的交互都隐藏在JavaScript对象ajaxSampleSvc的后面。更加令人惊讶的是,ajaxSampleSvc服务不是由手工编写而是完全自动生成的!让我们继续,看看这是如何做到的。

引入DWR

  如同在“原始的Ajax”一节所演示的那样,直接使用XmlHttpRequest创建异步请求非常麻烦。不仅JavaScript代码冗长,而且必须考虑服务器端为定位Ajax请求到适当的服务所需做的工作,并将结果封送到浏览器。

  设计DWR的目的是要处理将Web页面安装到后端服务上所需的所有信息管道。它是一个Java框架,可以很轻松地将它插入到Web应用程序中, 以便JavaScript代码可以调用服务器上的服务。它甚至直接与Spring Framework集成,从而允许用户直接向Web客户机公开bean。

  DWR真正的巧妙之处是,在用户配置了要向客户机公开的服务之后,它使用反射来生成JavaScript对象,以便Web页面能够使用这些对象 来访问该服务。然后Web页面只需接合到生成的JavaScript对象,就像它们是直接使用服务一样;DWR无缝地处理所有有关Ajax和请求定位的琐 碎细节。

  让我们仔细分析一下示例代码,弄清它是如何工作的。

应用程序细节:DWR分析

  关于应用程序,首先要注意的是,它是一个标准的Java应用程序,使用分层架构(Layered Architecture)设计模式。使用DWR通过JavaScript公开一些服务并不影响您的设计。

  下面是一个简单的Java服务,我们将使用DWR框架直接将其向JavaScript代码公开:

package com.tearesolutions.service;

public interface AjaxSampleSvc {
Article castVote(int rank);
}

  这是一个被简化到几乎不可能的程度的例子,其中只有一篇文章可以投票。该服务由Spring管理,它使用的bean名是ajaxSampleSvc,它的持久性需求则依赖于ArticleDao。详情请参见applicationContext.xml。

  为了把该服务公开为JavaScript对象,需要配置DWR,添加dwr.xml文件到WEB-INF目录下:














  dwr.xml文件告诉DWR哪些服务是要直接向JavaScript代码公开的。注意,已经要求公开Spring bean ajaxSampleSvc。DWR将自动找到由应用程序设置的SpringApplicationContext。为此,必须使用标准的servlet 过滤器ContextLoaderListener来初始化Spring ApplicationContext。

  DWR被设置为一个servlet,所以把它的定义添加到web.xml:




Ajax Examples



org.springframework.web.context.ContextLoaderListener




ajax_sample
com.tearesolutions.web.AjaxSampleServlet
1



dwr-invoker
DWR Servlet
Direct Web Remoter Servlet
uk.ltd.getahead.dwr.DWRServlet

debug
true




ajax_sample
/ajax_sample



dwr-invoker
/dwr/*


  做完这些之后,可以加载http://localhost:7001/ajax-demo/dwr,看看哪些服务可用。结果如下:

图3. 可用的服务

  单击ajaxSampleSvc链接,查看有关如何在HTML页面内直接使用服务的示例实现。其中包含的两个JavaScript文件完成了大部分的功能:


ajaxSampleSvc.js是动态生成的:

function ajaxSampleSvc() { }

ajaxSampleSvc.castVote = function(callback, p0)
{
DWREngine._execute(callback, '/ajax-demo/dwr',
'ajaxSampleSvc', 'castVote', p0);
}

  现在可以使用JavaScript对象ajaxSampleSvc替换所有的XmlHttpRequest代码,从而重构raw-ajax.html文件。可以在dwr-ajax.html文件中看到改动的结果;下面是新的JavaScript函数:

function castVote(rank) {
ajaxSampleSvc.castVote(processResponse, rank);
}
function processResponse(data) {
var voteText = "

Thanks for Voting!

"
+ "

Current ranking: " + data.voteAverage
+ " out of 5

"
+ "

Number of votes placed: "
+ data.numberOfVotes + "

";
502 502'votes').innerHTML = voteText;
}

  惊人地简单,不是吗?由ajaxSampleSvc对象返回的Article域对象序列化为一个JavaScript对象,允许在它上面调用诸 如numberOfVotes()和voteAverage()之类的方法。在动态生成并插入到DIV元素“votes”中的HTML代码内使用这些数 据。

下一步工作

   在后续文章中,我将继续有关Ajax的话题,涉及下面这些方面:

  • Ajax最佳实践

  像许多技术一样,Ajax是一把双刃剑。对于一些用例,其应用程序其实没有必要使用Ajax,使用了反而有损可用性。我将介绍一些不适合使用的模式,突出说明Ajax的一些消极方面,并展示一些有助于缓和这些消极方面的机制。例如,对Netflix电影浏览器来说,Ajax是合适的解决方案吗?或者,如何提示用户确实出了一些问题,而再次单击按钮也无济于事?

  • 管理跨请求的状态

  在使用Ajax时,最初的文档DOM会发生一些变化,并且有大量的页面状态信息存储在客户端变量中。当用户跟踪一个链接到应用程序中的另一个页面时,状态就丢失了。当用户按照惯例单击Back按钮时,呈现给他们的是缓存中的初始页面。这会使用户感到非常迷惑!

  • 调试技巧

  使用JavaScript在客户端执行更多的工作时,如果事情不按预期方式进行,就需要一些调试工具来帮助弄清出现了什么问题。

结束语

  本文介绍了Ajax方法,并展示了如何使用它来创建一个动态且响应灵敏的Web应用程序。通过使用DWR框架,可以轻松地把Ajax融合到站点中,而无需担心所有必须执行的实际管道工作。

  特别感谢Getahead IT咨询公司的Joe Walker和他的团队开发出DWR这样神奇的工具。感谢你们与世界共享它!

下载

  本文中演示的应用程序源代码可供下载:ajax-demo.war(1.52 MB)。

参考资料

原文出处

An Introduction To Ajax

http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html

抄下来感觉到自己随时都会用

星期三, 九月 06, 2006

星期日, 九月 03, 2006

cnBeta.COM - 习惯网络暴力 从不习惯网骂到不计较网骂?

cnBeta.COM - 习惯网络暴力 从不习惯网骂到不计较网骂?

一个朋友在一家小报上发表了一篇关于房地产市场的分析性文章,可能是触及了人们时下关注的焦点,于是网上点 击率一线飘红.文章被人关注总比无人理睬有意思啊!可是朋友却笑不起来!因为BBS上显示:在上百条留言中不乏骂人之作---根本就不讨论问题,指名道姓 地张嘴就骂:走狗!混蛋!放屁!×××是个混蛋吧!什么混蛋逻辑……

不知道骂人者想说什么?一个话题有争议本来是太正常不过的事儿,既可 以平心静气地研讨,亦可以唇枪舌剑地激辩……为什么一定要破口大骂呢?为什么不能在争鸣中求索出一些道理来?为什么非得落到既不尊重别人又自取其辱的尴尬 境地呢?然而,试看今日之网络“网骂” 之风一日甚过一日,有始作俑者就有步后尘者.人们似乎已经见怪不怪了,更有人美其名曰:这正是网络自由惟一吸引“人气”的缘由,想唱就唱,想骂就骂,不骂 白不骂!



网络平台,虚拟世界.在网上用实名发帖的人非常之少,骂人者大都是匿名的隐士,似乎无所谓负责任也无所谓讲原则,而只有“网骂”自由是真实的.所以网上盛 行不骂白不骂——自己先痛快了再说!被骂者中也有大不以为然的——网上的事儿谁还当真?你骂吧,骂了也白骂,清者自清.然而正是在这声声叫骂中,我们的互 联网真的成了不断生产垃圾的垃圾场,一个数字时代的高科技产物竟成了有些没有教养的现代人粗鄙情怀的发泄地.

对于“网骂”还有人振振有辞:对任何事情都不能用数字世界的二进制逻辑——“对错”或“好坏”来简单评判.这个道理无疑是普遍正确的,但在分析对待“网 骂”这个具体问题上却用错了地方.于是,“网骂”真的无益于人类健康吗?真的无益于社会文明和进步吗?真的无益于互联网的发展吗?真的无益于人与人之间的 沟通吗?真的无益于矛盾分歧的解决吗?本该毫无疑义的结论在现实中却生发了反复诘问的必要.

面对“网骂”似乎是在考验一个人的气度、心胸、见识、水平.您要是真能仰天一笑全忘了,那是卓尔不群;您要是怒目而视口诛笔伐,那就太小家子气;您要是为 此惴惴不安自惭形秽,那叫没见过世面;您要是以牙还牙接着大骂,才算本事……然而,“网骂”其实是在麻木一个人的灵魂、理性、良知、德性.您将在谩骂中渐 渐习惯,久闻其臭而不觉臭——逻辑思维能力潜移默化地退化,明辨是非的大脑变得越来越迟钝,胸中的正义感一点一点地丧失,心灵深处被污垢悄悄覆盖……您可 能变得“大度” 了,却丧失了一个人最宝贵的品质——正直.

面对“网骂”更像是在检验一个社会的社会规范、文明程度、整合能力以及公民自律水准.在这样一个地方不仅有言论的“自由”,连骂人都不受任何“制约”;然 而,不愿意挨骂者的自由还存在吗?且不说“网骂”对挨骂者人格、心理成长的负面影响,对骂人者难道不同样具有杀伤力吗?放纵整个社会沉浸在逻辑混乱的谩骂 声中,让公民们沉迷于令人晕眩的似是而非的状态里,这难道不是社会规范的失控吗?这样的社会氛围可能会变得“宽容”了,但一个社会将失去最重要的价值判断 ——正义.

分析任何问题,简单僵化的思维方式无益,而陷入诡辩论的泥沼则更无益,以偏概全是不能真正解决问题的.开放、自由、率性无疑是网络BBS的魅力所在.然 而,追求自由、表现率性是有度的.面对竞争社会的重重压力,每个人都需要宣泄,让自己心中的阴霾一扫而出,以达到平衡.正是从这个意义上说,人们在网络上 的宣泄需求是可以理解的.但是真正成熟的人应该用自己的思想去征服别人,真正和谐的社会是用理性战胜非理性,而不是用“网骂”解脱自己,用攻击别人,构筑 社会中人与人之间的对立.

联合国秘书长科菲·安南在2004年纽约互联网治理全球论坛上曾说过这样的话:短短几年间,互联网彻底改变了人类通信与交流的架构.它所具有的潜力远远大 于我们在它诞生后的这一小段日子里所见到的.在管理、推动和保护互联网健康发展的过程中,我们必须与缔造者一样富有创新精神.毫无疑问,互联网需要治理, 但并不意味着我们需要沿用传统的方式,毕竟互联网是如此的不同.

因此,建立真正富有创新精神的网络规范刻不容缓,虽然这并不能使“网骂”在一个早上销声匿迹,但一定会让“网骂”者受到制约和惩罚,学会尊重,学会沟通; 从而把网络BBS打造成为提升网民思辨能力的智力空间,逐步培养起网民之间宽容友爱的交往习惯,让网络世界变得美好而干净.

再啰嗦一句:从不习惯“网骂”到不计较“网骂”——这可不是人类的进步.倘若纵容“网骂”,互联网上的垃圾场就会演变为整个社会的垃圾场,这绝非耸人听闻.



太多了,对此也深有感触。流下来慢慢看。

虽然不愿意承认,Foobar的美化真的可以出皮肤了 - Jensen's Blog - 5dblog.com

虽然不愿意承认,Foobar的美化真的可以出皮肤了 - Jensen's Blog - 5dblog.com


Foobar的新插件真是越来越牛了,特别是最近出的trackinfo mod和single column playlist。这两个东西简直就是为了给foobar做皮肤出的……

trackinfo mod可以在面板里的任意位置加入任意字体字号的文字,还可以给文字加上阴影效果:


而single column playlist插件可以在每一条播放列表项目上都实现这个效果,而且single column playlist还可以很好的自动把专辑分组:


更牛的是两个插件都可以随意在面板里的任意位置加入图片:


任意位置加入文字或至图片,而且可以自由的由函数控制,这样就可以完美的和Foobar强大功能配合,而且,实现foobar的界面也开始注重PS的实力,如果能吸引到一些PS高手的话,加上好的代码,就可以实现极其华丽的界面!
所以,虽然不愿意承认,Foobar的美化真的不能只叫设置了,真的可以出皮肤了!
(偶自认ps水平一般,恐怕以后要落后了……)

现在这两个插件都处在测试阶段,只有trackinfo mod算是比较完善了,不过估计很快就会推出稳定版,到时候Foobar的界面就真的可以赶超winamp了!

这两个插件我都在研究之中,无奈时间不多,暂时出不了什么作品,以后等完善了一定要用它们再弄个强大又好看的foobar!


喜欢黑冰的美化版本。呵呵希望他早日研究好给我们带来更有趣的Foobar。

时间被消磨

游戏。呵呵

EQ?WOW。DDO
哦中间还有个EQ2

消耗了我N多的时间。突然想放下一切。但是每次都停不下来。空虚的自己用虚拟的世界去填补。

唉小小的牢骚后还是继续的游戏吧。

人类最为大的发明其实是游戏。让非常多的人去消磨自己的时间。
Google接手后果然不一样了。我越来越喜欢blogger了。 开始把以前在spaces的东西转移过来。