Ajax的工作原理


Posted in 面试题 onDecember 04, 2015
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和请求定位的琐碎细节。

Tags in this post...

面试题 相关文章推荐
PHP面试题-$message和$$message的区别
Dec 08 面试题
PHP如何自定义函数
Sep 16 面试题
Java如何格式化日期
Aug 07 面试题
金智子午JAVA面试题
Sep 04 面试题
C语言笔试题
Sep 04 面试题
介绍一下SQL中union,intersect和minus
Apr 05 面试题
sealed修饰符是干什么的
Oct 23 面试题
如何进行Linux分区优化
Feb 12 面试题
为什么需要版本控制
Oct 28 面试题
介绍一下MYSQL常用的优化技巧
Oct 25 面试题
你在项目中用到了xml技术的哪些方面?如何实现的?
Jan 26 面试题
JAVA招聘远程笔试题
Jul 23 面试题
什么是GWT的Module
Jan 20 #面试题
Prototype如何实现页面局部定时刷新
Aug 06 #面试题
如何开发一个JQuery插件
Jul 28 #面试题
什么是GWT的Entry Point
Aug 16 #面试题
AJAX的优缺点都有什么
Aug 18 #面试题
DOM和JQuery对象有什么区别
Nov 11 #面试题
主要的Ajax框架都有什么
Nov 14 #面试题
You might like
自己前几天写的无限分类类
2007/02/14 PHP
php变量作用域的深入解析
2013/06/03 PHP
PHP 实现类似js中alert() 提示框
2015/03/18 PHP
PHP url的pathinfo模式加载不同控制器的简单实现
2016/08/12 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
2018/05/25 PHP
调试php程序的简单步骤
2019/10/04 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
一个js写的日历(代码部分网摘)
2009/09/20 Javascript
javascript contains和compareDocumentPosition 方法来确定是否HTML节点间的关系
2010/02/04 Javascript
Document.location.href和.replace的区别示例介绍
2014/03/04 Javascript
javascript日期格式化示例分享
2014/03/05 Javascript
jQuery禁用键盘后退屏蔽F5刷新及禁用右键单击
2016/01/22 Javascript
JS+Canvas实现的俄罗斯方块游戏完整实例
2016/12/12 Javascript
javascript简单写的判断电话号码实例
2017/05/24 Javascript
Bootstrap Table实现定时刷新数据的方法
2018/08/13 Javascript
JS使用H5实现图片预览功能
2019/09/30 Javascript
vant中的toast层级改变操作
2020/11/04 Javascript
Python实现比较两个列表(list)范围
2015/06/12 Python
python 中的divmod数字处理函数浅析
2017/10/17 Python
Windows环境下python环境安装使用图文教程
2018/03/13 Python
python抓取网站的图片并下载到本地的方法
2018/05/22 Python
python的concat等多种用法详解
2018/11/28 Python
python获取Pandas列名的几种方法
2019/08/07 Python
Python读取表格类型文件代码实例
2020/02/17 Python
Python通过Pillow实现图片对比
2020/04/29 Python
pytorch学习教程之自定义数据集
2020/11/10 Python
html5+CSS3+JS实现七夕言情功能代码
2017/08/28 HTML / CSS
生物专业个人自荐信范文
2013/11/29 职场文书
幼儿教育感言
2014/02/05 职场文书
党校学习自我鉴定
2014/02/24 职场文书
心理健康活动总结
2014/04/30 职场文书
学生保证书格式
2015/02/27 职场文书
幼儿园毕业致辞
2015/07/29 职场文书
关于感恩老师的古诗句
2019/08/20 职场文书
golang json数组拼接的实例
2021/04/28 Golang
基于JavaScript实现年月日三级联动
2021/06/22 Javascript