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两种查询函数array/row的区别
Jun 03 面试题
什么是接口(Interface)?
Feb 01 面试题
我的applet原先好好的, 一放到web server就会有问题,为什么?
May 10 面试题
static全局变量与普通的全局变量有什么区别
May 27 面试题
利达恒信公司.NET笔试题面试题
Mar 05 面试题
Linux内核的同步机制是什么?主要有哪几种内核锁
Jan 03 面试题
Linux的主要特性
Oct 06 面试题
简述进程的启动、终止的方式以及如何进行进程的查看
Jul 12 面试题
外包公司软件测试工程师
Nov 01 面试题
介绍一下EJB的分类及其各自的功能及应用
Aug 23 面试题
掌上明珠Java程序员面试总结
Feb 23 面试题
同步和异步有何异同,在什么情况下分别使用他们
Apr 09 面试题
什么是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
php 输出双引号"与单引号'的方法
2010/05/09 PHP
PHP内置过滤器FILTER使用实例
2014/06/25 PHP
简单谈谈PHP vs Node.js
2015/07/17 PHP
简单实现php上传文件功能
2017/09/21 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
javascript各种复制代码收集
2008/09/20 Javascript
js onkeypress与onkeydown 事件区别详细说明
2012/12/13 Javascript
javascript获得当前的信息的一些常用命令
2015/02/25 Javascript
jQuery实现不断闪烁文字的方法
2015/05/15 Javascript
jQuery插件AjaxFileUpload实现ajax文件上传
2016/05/05 Javascript
JavaScript基于自定义函数判断变量类型的实现方法
2016/11/23 Javascript
JS判断微信扫码的方法
2017/08/07 Javascript
代码实例ajax实现点击加载更多数据图片
2018/10/12 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
2019/03/05 Javascript
JS中的算法与数据结构之栈(Stack)实例详解
2019/08/20 Javascript
js实现提交前对列表数据的增删改查
2020/01/16 Javascript
vue-cli3单页构建大型项目方案
2020/04/07 Javascript
JavaScript实现与web通信的方法详解
2020/08/07 Javascript
vue style width a href动态拼接问题的解决
2020/08/07 Javascript
[04:31]2016国际邀请赛中国区预选赛妖精采访
2016/06/27 DOTA
Python 正则表达式操作指南
2009/05/04 Python
python实现获取客户机上指定文件并传输到服务器的方法
2015/03/16 Python
Python随机生成数模块random使用实例
2015/04/13 Python
Python smallseg分词用法实例分析
2015/05/28 Python
django 发送手机验证码的示例代码
2018/04/25 Python
pandas通过字典生成dataframe的方法步骤
2019/07/23 Python
最新pycharm安装教程
2020/11/18 Python
Fanatics官网:运动服装、球衣、运动装备
2020/10/12 全球购物
附答案的Java面试题
2012/11/19 面试题
通息工程毕业生自荐信
2013/10/16 职场文书
致跳高运动员广播稿
2014/01/13 职场文书
检查接待方案
2014/02/27 职场文书
驻村工作先进事迹
2014/08/14 职场文书
城市规划应届生推荐信
2014/09/08 职场文书
民主评议党员个人总结
2015/02/13 职场文书
高中政治教师教学反思
2016/02/23 职场文书