- 浏览: 273056 次
- 性别:
- 来自: 东方水城
文章分类
最新评论
-
18335864773:
pageoffice 插件 可以实现 office文档的在线操 ...
Java调用com组件操作word -
coosummer:
推荐使用在线免费bug管理系统- bug 禅思:http:// ...
Bug管理工具 -
program_coco:
柠檬bug管理系统,一个在线的bug管理系统。www.lemo ...
Bug管理工具 -
影非弦:
这个in.read(data);//data是一个byte[] ...
Java串口通信总结 -
影非弦:
这个不详细啊,我弄了一天了,都没弄出来,总是出错,读信息的时候 ...
Java串口通信总结
本文介绍了五种常见 Ajax 设计模式。它们在使用 HTML、XML 和 JavaScript 代码从服务器获取数据方面有所不同。我先介绍最简单的模式,它将使用来自服务器的新 HTML 页面来更新页面。
模式1:替换 HTML 片段
最常见的 Ajax 任务也许就是向服务器请求更新的 HTML 并使用它更新部分页面。可能需要周期性地完成这一任务 —— 比如,更新股市报价。也可能要按需更新 —— 比如,对搜索请求进行响应。
清单1
中的代码从服务器请求一个页面然后将内容放入页面主体的 <div>
标记中。
清单 1. Pat1_replace_div.html <html> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dobj = document.getElementById( 'htmlDiv' ); dobj.innerHTML = req.responseText; } } function loadUrl( url ) { if(window.XMLHttpRequest) { try { req = new XMLHttpRequest(); } catch(e) { req = false; } } else if(window.ActiveXObject) { try { req = new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) { try { req = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { req = false; } } } if(req) { req.onreadystatechange = processReqChange; req.open('GET', url, true); req.send(''); } } var url = window.location.toString(); url = url.replace( /pat1_replace_div.html/, 'pat1_content.html' ); loadUrl( url ); </script> <body> Dynamic content is shown between here:<br/> <div id="htmlDiv" style="border:1px solid black;padding:10px;"> </div> And here.<br/> </body> </html>
清单2 展示了代码请求的内容。
清单 2. Pat1_content.html HTML encoded content goes here.
在 Firefox 中加载页面后,可以看到 图 1 所示的结果。
现在回到 清单1
中的代码,来观察一些内容。第一个要注意的是 loadUrl()
函数,它从服务器请求一个 URL。该函数使用 XMLHTTPRequest
对象向服务器请求新内容。它还指定了一个回调函数 —— 本例中,是 processReqChange
—— 当浏览器收到内容时将调用它。
processReqChange
函数将查看对象以确定请求是否完成。如果是的话,该函数将页面 <div>
标记的 innerHTML
设置为响应的文本。
将 <div>
标记作为一个动态内容的占位符,这是 Ajax 代码的主要组成部分。这些标记没有可见的表示形式(除非添加边框,像我这样做),但它们很好地标记了内容的放置位置。工程师还使用 <span>
标记用于可代替的片段,稍后我将对其进行演示。<div>
和 <span>
标记的不同之处是前者加入了一个断行符(如一个段落),而后者使用边线勾画出一节内联文本。
暂时回到 processReqChange
函数,该函数对 status
和 readyState
的值进行检查非常重要。有些浏览器可能只在请求完成时才调用这个函数,而也有些浏览器会不断回调该函数从而告诉代码请求依然在运行。
该模式的另一种变体就是创建一个选项卡样式的显示。 清单3 展示了一个简单的选项卡式 Ajax 界面。
清单 3. Pat1_tabs.html <html> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dobj = document.getElementById( 'tabDiv' ); dobj.innerHTML = req.responseText; } } function loadUrl( tab ) { var url = window.location.toString(); url = url.replace( /pat1_tabs.html/, tab ); ... } function tab1() { loadUrl( 'pat1_tab1_content.html' ); } function tab2() { loadUrl( 'pat1_tab2_content.html' ); } tab1(); </script> <body> <a href="javascript: void tab1();">Tab 1<a> <a href="javascript: void tab2();">Tab 2<a> <div id="tabDiv" style="border:1px solid black;padding:10px;"> </div> </body> </html>
清单4 显示了第一个选项卡的内容。
Tab 1 content
清单 5 显示了第二个选项卡的内容。
Tab 2 content
当我在自己的浏览器上显示该页面时,我看到了第一个选项卡,如 图 2 所示
然后单击第二个选项卡的链接。浏览器检索第二个选项卡的内容然后将它显示在选项卡区域,如 图 3 所示。
这是该设计模式的最典型用法 —— 从用户那里获得请求并使用新的内容更新部分显示,本例演示了创建选项卡显示的技巧。应用程序端的价值就是您可以为用户下载非常轻量级的页面,用户可以根据自己的需求访问这些内容。
在 Ajax 出现之前,最常见的技术是将所有的选项卡都放在页面上,然后根据需要显示或隐藏它们。这就是说即使从来不查看第二个选项卡,也会为其创建 HTML,既浪费服务器时间又浪费带宽。使用这种新的 Ajax 方法,只有当用户请求第二个选项卡时才会为其创建 HTML。
该模式的另一个变化就是 Read more 链接,如 图 4 所示。
假如想希望阅读更多关于我遛狗的经历,可以单击 Read more 链接,使该链接替换为完整的故事,如 图 5 所示。
这样做的好处是顾客可以在无需刷新页面的情况下获得更多内容。
清单 6 显示了该页的代码。
<html> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dobj = document.getElementById( "moreSpan" ); dobj.innerHTML = req.responseText; } } function loadUrl( url ) { ... } function getMore() { var url = window.location.toString(); url = url.replace( /pat1_readmore.html/, 'pat1_readmore_content.html' ); loadUrl( url ); } </script> <body> <h1>Walking the dog</h1> I took my dog for a walk today. <span id="moreSpan"> <a href="javascript: void getMore()">Read more...</a> </span> </body> </html>
清单 7 显示了 “read more” 部分的内容。
清单 7. Pat1_readmore_content.html
It was a nice day out. Warm and sunny. My dog liked getting out for a stretch. |
这些代码演示的是 <span>
标记的用法,而非 <div>
标记。所使用的方法取决于用户界面(UI)的需求。但是正如您所看到的那样,无论哪种方法使用起来都很简单。
为页面获取新的 HTML 只是其中一件事情,如果您希望 JavaScript 代码在页面中使用数据执行一些更智能化的任务该怎么办呢?如何使用结构化的方式将数据发送到浏览器呢?毫无疑问,这正是使用 XML 的原因。
模式 2. 读取 XML 数据
出于某些原因,Ajax 已成为 XML 的同义词,尽管 XML 不是绝对必要的。从上面几个例子可以看出,您完全可以返回简单的文本甚至是 HTML 片段 —— 或者 Extensible HTML(XHTML)—— 代码。但是发送 XML 自有其优势所在。
清单 8 显示的 Ajax 代码首先向服务器请求图书记录,然后将数据显示在页面内的表格中。
- < html >
- < head >
- < script >
- var req = null ;
- function processReqChange() {
- if (req.readyState == 4 && req.status == 200 && req.responseXML ) {
- var dtable = document .getElementById( 'dataBody' );
- var nl = req .responseXML.getElementsByTagName( 'book' );
- for( var i = 0 ; i < nl.length ; i++ ) {
- var nl nli = nl.item( i );
- var elAuthor = nli .getElementsByTagName( 'author' );
- var author = elAuthor .item(0).firstChild.nodeValue;
- var elTitle = nli .getElementsByTagName( 'title' );
- var title = elTitle .item(0).firstChild.nodeValue;
- var elTr = dtable .insertRow( -1 );
- var elAuthorTd = elTr .insertCell( -1 );
- elAuthorTd.innerHTML = author ;
- var elTitleTd = elTr .insertCell( -1 );
- elTitleTd.innerHTML = title ;
- } } }
- function loadXMLDoc( url ) {
- if(window.XMLHttpRequest) {
- try { req = new XMLHttpRequest();
- } catch(e) { req = false ; }
- } else if(window.ActiveXObject) {
- try { req = new ActiveXObject('Msxml2.XMLHTTP');
- } catch(e) {
- try { req = new ActiveXObject('Microsoft.XMLHTTP');
- } catch(e) { req = false ; }
- } }
- if(req) {
- req.onreadystatechange = processReqChange ;
- req.open('GET', url, true);
- req.send('');
- }
- }
- var url = window .location.toString();
- url url = url.replace( /pat2_xml.html/, 'pat2_xml_data.xml' );
- loadXMLDoc( url );
- </ script >
- </ head >
- < body >
- < table cellspacing = "0" cellpadding = "3" width = "100%" >
- < tbody id = "dataBody" >
- < tr >
- < th width = "20%" > Author </ th >
- < th width = "80%" > Title </ th >
- </ tr >
- </ tbody >
- </ table >
- </ body >
- </ html >
<html> <head> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 && req.responseXML ) { var dtable = document.getElementById( 'dataBody' ); var nl = req.responseXML.getElementsByTagName( 'book' ); for( var i = 0; i < nl.length; i++ ) { var nli = nl.item( i ); var elAuthor = nli.getElementsByTagName( 'author' ); var author = elAuthor.item(0).firstChild.nodeValue; var elTitle = nli.getElementsByTagName( 'title' ); var title = elTitle.item(0).firstChild.nodeValue; var elTr = dtable.insertRow( -1 ); var elAuthorTd = elTr.insertCell( -1 ); elAuthorTd.innerHTML = author; var elTitleTd = elTr.insertCell( -1 ); elTitleTd.innerHTML = title; } } } function loadXMLDoc( url ) { if(window.XMLHttpRequest) { try { req = new XMLHttpRequest(); } catch(e) { req = false; } } else if(window.ActiveXObject) { try { req = new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) { try { req = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { req = false; } } } if(req) { req.onreadystatechange = processReqChange; req.open('GET', url, true); req.send(''); } } var url = window.location.toString(); url = url.replace( /pat2_xml.html/, 'pat2_xml_data.xml' ); loadXMLDoc( url ); </script> </head> <body> <table cellspacing="0" cellpadding="3" width="100%"> <tbody id="dataBody"> <tr> <th width="20%">Author</th> <th width="80%">Title</th> </tr> </tbody> </table> </body> </html>
清单 9 显示了该页面的数据。
- < books >
- < book >
- < author > Jack Herrington </ author >
- < title > Code Generation in Action </ title >
- </ book >
- < book >
- < author > Jack Herrington </ author >
- < title > Podcasting Hacks </ title >
- </ book >
- < book >
- < author > Jack Herrington </ author >
- < title > PHP Hacks </ title >
- </ book >
- </ books >
<books> <book> <author>Jack Herrington</author> <title>Code Generation in Action</title> </book> <book> <author>Jack Herrington</author> <title>Podcasting Hacks</title> </book> <book> <author>Jack Herrington</author> <title>PHP Hacks</title> </book> </books>
在浏览器中加载页面时,我看到了如 图 6 所示的结果.
此页面和上一个模式中显示的页面之间最大的区别就是 processReqChange
函数,这里没有使用 responseText
,而是 responseXML
,这是一个 XML 文档对象模型(Document Object Model,DOM),该模型只有在来自服务器的响应是正确编码的 XML 时才是可用的。
通过使用 responseXML
,我请求了 XML 文档的 <book>
标记的列表。然后分别从中获取 <title>
和 <author>
元素。接下来,为每本书向表中添加一行,再为每行添加包含作者和题目数据的单元格。
这是 XML 数据的最基本应用。更复杂的 JavaScript 代码可以执行客户端排序或根据返回的数据进行搜索。
遗憾的是,传递 XML 数据的缺点是需要浏览器多花费一些时间来解析整个 XML 文档。同样,JavaScript 代码在 XML 中查找数据也很复杂(参见 清单 8 )。一个替代办法是从服务器请求 JavaScript 代码。
从服务器请求 JavaScript 数据这种技术通常用于 JavaScript Object Notation (JSON)这种良好的代码。返回 JavaScript 数据的优点就是能够使浏览器高效地解析并创建使用起来更加简单的 JavaScript 数据结构。
让我们将 清单 8 中从服务器读取 XML 的代码修改为从服务器读取 JavaScript 数据的代码。新代码如 清单 10 所示。
- < html > < head > < script >
- var req = null ;
- function processReqChange() {
- if (req.readyState == 4 && req.status == 200 ) {
- var dtable = document .getElementById( 'dataBody' );
- var books = eval ( req.responseText );
- for( var b in books ) {
- var elTr = dtable .insertRow( -1 );
- var elAuthorTd = elTr .insertCell( -1 );
- elAuthorTd.innerHTML = books [b].author;
- var elTitleTd = elTr .insertCell( -1 );
- elTitleTd.innerHTML = books [b].title;
- } } }
- ...
<html><head><script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var dtable = document.getElementById( 'dataBody' ); var books = eval( req.responseText ); for( var b in books ) { var elTr = dtable.insertRow( -1 ); var elAuthorTd = elTr.insertCell( -1 ); elAuthorTd.innerHTML = books[b].author; var elTitleTd = elTr.insertCell( -1 ); elTitleTd.innerHTML = books[b].title; } } } ...
所有的 HTML 代码保持不变。processReqChange
函数仅仅更改为读取 eval
从而从服务器返回 JavaScript 数据。该函数随后使用 eval
的 JavaScript 对象作为数据源,后者又将其添加到表中。
清单 11 显示了来自服务器的 JavaScript 数据。
- [ { author: 'Jack Herrington', title: 'Code Generation in Action' },
- { author: 'Jack Herrington', title: 'Podcasting Hacks' },
- { author: 'Jack Herrington', title: 'PHP Hacks' }
- ]
[ { author: 'Jack Herrington', title: 'Code Generation in Action' }, { author: 'Jack Herrington', title: 'Podcasting Hacks' }, { author: 'Jack Herrington', title: 'PHP Hacks' } ]
为什么众多 Ajax 应用程序工程师更喜欢使用 JavaScript 代码而不是 XML 来对数据编码?答案很明显。JavaScript 代码更容易读取和管理,并且也更容易被浏览器处理。
收集和显示所有的数据之后,即可看到 Ajax 的重点就是显示当前数据 —— 当前 最重要的部分。那么,如何保证总是能够从服务器获得最新的数据呢?
浏览器会尝试化 Web 流量,所以如果您对同一个 URL 请求两次,很可能还不如重新请求一次页面,您的浏览器将仅仅使用浏览器缓存中存储的页面。所以,Ajax 应用程序中另一个常见模式是使用 URL 中的随机元素来保证浏览器不会返回一个缓存的结果。
向URL添加当前时间的数字值。 清单 12 展示了这一技巧
- < html >
- < script >
- ...
- function loadUrl( url ) {
- url url = url + "? t ="+((new Date()).valueOf());
- ...
- }
- ...
<html> <script> ... function loadUrl( url ) { url = url + "?t="+((new Date()).valueOf()); ... } ...
代码取自 清单 1
,对 URL 字符串执行了一些额外的 JavaScript 文本操作。我将 URL 连接到一个新的参数 t
,它具有一个时间值。服务器是否能识别这个值实际上并不重要。这只不过是用来确保浏览器忽视其基于 URL 的页面缓存。
最后要演示的这个模式是第一个模式的高级版本:包含来自服务器内容的 <div>
标记的替代物。Web 应用程序中的一个常见问题是在响应用户输入时,必须更新显示页面中的一些区域。举例来说,在一个股票报价应用程序中,显示页面的一部分可能会展示最近的报价,而另一部分则显示最近报价的列表。
为更新显示页面中的多个区域,我使用了服务器的 XML 响应,它包含每个部分的数据。然后,使用一个正则表达式将响应分解为单个部分。清单 13 显示了这种技巧。
清单 13. Pat5_multi_segment.html
- < html >
- < head >
- < script >
- var req = null ;
- function processReqChange() {
- if (req.readyState == 4 && req.status == 200 ) {
- var one = req .responseText.match( /\ < one \ > (.*?)\ < \/one\ > / );
- document.getElementById( 'divOne' ).innerHTML = one [1];
- var two = req .responseText.match( /\ < two \ > (.*?)\ < \/two\ > / );
- document.getElementById( 'divTwo' ).innerHTML = two [1];
- } }
- function loadXMLDoc( url ) { ... }
- var url = window .location.toString();
- url url = url.replace( /pat5_multi_segment.html/, 'pat5_data.xml' );
- loadXMLDoc( url );
- </ script >
- </ head >
- < body >
- This is the content for segment one:< br />
- < div id = "divOne" style = "border:1px solid black;padding:10px;" >
- </ div >
- And segment two:< br />
- < div id = "divTwo" style = "border:1px solid black;padding:10px;" >
- </ div >
- </ body >
- </ html >
<html> <head> <script> var req = null; function processReqChange() { if (req.readyState == 4 && req.status == 200 ) { var one = req.responseText.match( /\<one\>(.*?)\<\/one\>/ ); document.getElementById( 'divOne' ).innerHTML = one[1]; var two = req.responseText.match( /\<two\>(.*?)\<\/two\>/ ); document.getElementById( 'divTwo' ).innerHTML = two[1]; } } function loadXMLDoc( url ) { ... } var url = window.location.toString(); url = url.replace( /pat5_multi_segment.html/, 'pat5_data.xml' ); loadXMLDoc( url ); </script> </head> <body> This is the content for segment one:<br/> <div id="divOne" style="border:1px solid black;padding:10px;"> </div> And segment two:<br/> <div id="divTwo" style="border:1px solid black;padding:10px;"> </div> </body> </html>
清单 14 展示了来自服务器的数据。
- < segments >
- < one > Content for segment one </ one >
- < two > Content for segment < b > two </ b > </ two >
- </ segments >
<segments> <one>Content for segment one</one> <two>Content for segment <b>two</b></two> </segments>
在浏览器中加载这段代码时,将看到 图 7 所示的结果。
在页面代码中,我还可以使用 XML 响应,因为服务器返回的是有效的 XML。但是使用正则表达式比从 XML 代码中分解单独部分更加简单。
Ajax 的功能之强大与之被误解和误用的程度相当。本文中演示的模式为在 Web 应用程序中使用 Ajax 提供了一个不错的起点。除了使用这里提供的代码,我还建议您关注以下 Web 2.0 革命带来的某些出色的 Ajax 和 Web UI 库。其中最主要的是 Prototype.js 库,它提供了向浏览器发送以及从浏览器获取数据的简便方法,以及浏览器间兼容的方法更新 Web 页面内容。使用这些库的价值在于工程师可以在广泛的浏览器和平台上专注地维护和测试它们,这样可省去大量的工作和麻烦。
无论从哪方面说,就像本文中的模式演示的那样,Ajax 可以为您的应用程序添加动态行为。
原载: http://www.ibm.com/developerworks/cn/xml/x-ajaxxml2/
评论
json效率貌似高点
浏览器get时才有缓存的情况,我一般用Math.random。
--
模式3读取的是json数据,可以考虑下js脚本~
觉得xml看似简单其实有点难。。。
发表评论
-
LongBoo-Ajax可视化RIA设计
2008-12-30 14:52 1738LongBoo- Ajax 框架是跨浏览器的JavaScri ... -
AJAX框架:Rialto的使用
2008-12-26 10:30 1578Rialto是一个跨浏 ... -
强烈推荐:240多个jQuery插件
2008-12-26 08:46 1364文件上传(File upload) Ajax File ... -
Ajax读取Text格式的数据
2008-12-25 11:24 24261.文本文件名:data.txt,其中内容如下所示: 文本测试 ... -
Ajax读取XML格式的数据
2008-12-25 11:12 15781.XML文件为:data.xml <?xml vers ... -
非常精美的ext桌面系统,超级帅
2008-12-18 08:57 3015预览地址:http://www.qwikioffice.co ... -
Mootools框架
2008-12-16 11:36 1805一.教程/文章/代码实例: http://cli ...
相关推荐
读取XML数据模式3.读取JavaScript数据模式4.避免浏览器缓存模式5.替换多个HTML片段结束语下载参考资料的确,Ajax是Web2.0热门术语,所有人都希望将其应用于自己的站点。但是它对我们究竟有什么意义?工程师该如何在...
这些新的界面常常被称作小部件,它们使用AsynchronousJavaScript+XML(Ajax)与服务器通信。本文介绍了五个可用于增强站点交互性的小部件。 Web2.0强调以独特、新颖的方式与网站的客户交互。其中很多创新技术都使用...
在本系列前面的文章中,我们使用普通文本和名/值参数发送数据,但XML也是一种可行的格式。本文将介绍如何来这样做。但最重要的是,我将讨论为何可以使用 XML作为请求格式,以及为何在多数情况下不应该使用它。
ajax调用xml ajax调用htmlajax调用xml ajax调用htmlajax调用xml ajax调用htmlajax调用xml ajax调用htmlajax调用xml ajax调用htmlajax调用xml ajax调用htmlajax调用xml ajax调用htmlajax调用xml ajax调用htmlajax调用...
您将探索如何使用Ajax来增强站点并使其具有Web 2.0的感觉,以及其他JavaScript增强如何将Web浏览器和网站变成真正的应用程序。
xml和AJAX实例源码 <br>XML,Ajax,C# 编写.admin 是管理后台 func脚本文件 Ajax <br>Ajfunc 是处理Ajax的C#代码 <br>.NET2.0 环境. <br>可以实现友情链接分类管理、添加及修改
只实现很简单的功能,使用XML储蓄,速度还可以,暂时没有优化.本人人品问题,仅支持IE5以上版本。 1.使用该控件需要空间支持目录写权限. 2.控件会在根目录下自动生成以下文档: 1.xml/xml/shopclass.xml //手动添加...
ajax发送xml请求小示例
Ajax 解析XML+json总结,很好的资源哦。欢迎大家来下载。
jquery结合ajax和xml实现省市县三级联动,chaojixuan
ajax传输xml
蓝驿轨迹-ajax+xml实现省市区无刷新联动源码 帮助: 1.前台添加html控件 <script language="javascript" src="js/PCA.js"></script> <!--省市区--> ...
利用Ajax读取XML文件实例,实现简单的无刷新效果
ajax导出xml调用浏览器下载功能; ajax导入文件说明及注意事项
Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex Ajax struts2 xml flex
通过DOM和Ajax使用XML_从菜鸟到专家2006
ajax很好的实例,内附源码。
本案例是一个基于xml的Ajax案例 Ajax通过解析xml来做出响应
如果您正在使用异步JavaScript和XML(Ajax)进行 Java:trade_mark: Web开发,那么您最关心的问题可能就是把数据从服务器传递给客户机。本文介绍了Java对象序列化的五种方式,并提供了选择最适合应用程序的数据格式和...