Ajax 编程技术 第四章 Ajax 技术

42
主主主主 主主 主主主主 主主 [email protected] [email protected] Ajax 编编编编 编编编 Ajax 编编

description

Ajax 编程技术 第四章 Ajax 技术. 4.1 XMLHttpRequest 对象. 本章主要介绍技术是 XMLHttpRequest 对象,因为 Ajax 应用程序的中心就是它。同时,对于许多数网页开发的实际问题中,它也是最广泛适用的解决方案。 我们还将介绍该对象的 GET 和 POST 方法的使用。同时探讨用户使用此对象常见的错误,例如当试图让页面在所有服务器上都能运行时遇到的一些问题。 最后还介绍一种 Ajax 技术的替代方案及其示例。. 4.1 XMLHttpRequest 对象. - PowerPoint PPT Presentation

Transcript of Ajax 编程技术 第四章 Ajax 技术

主讲教师:李艺主讲教师:李艺[email protected]@ustc.edu.cn

Ajax 编程技术第四章 Ajax 技术

4-2 中国科大《 Ajax编程技术》

4.1 XMLHttpRequest 对象

本章主要介绍技术是 XMLHttpRequest对象,因为 Ajax应用程序的中心就是它。同时,对于许多数网页开发的实际问题中,它也是最广泛适用的解决方案。

我们还将介绍该对象的 GET和 POST方法的使用。同时探讨用户使用此对象常见的错误,例如当试图让页面在所有服务器上都能运行时遇到的一些问题。

最后还介绍一种 Ajax技术的替代方案及其示例。

4-3 中国科大《 Ajax编程技术》

4.1 XMLHttpRequest 对象

XMLHttpRequest对象最初是作为 IE5中的一个ActiveX控件出现的,随后Mozilla 1.0、 Netscape7、Safari1.2和 Opera7.60都将它纳入自身。

XMLHttpRequest对象在 IE浏览器和非 IE浏览器中实现方法不同。

XMLHttpRequest对象的作用在于,允许用脚本程序通过 HTTP连接到服务器,而不比通过 HTTP请求响应模型与服务器通信。

4-4 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

创建 XMLHttpRequest对象在 IE7、 Firefox、 safari和 Opera中创建该对象的 JavaScript代码为:var xmlRequet = new XMLHttpRequest();

在 IE5/6中代码为:var xmlRequest = new ActiveXObject(“Microsoft.XMLHTTP”);

注意, JavaScript区分大小写,如果大小写不正确,什么东西都创建不出来。

使用 XMLHttpRequest对象的方式有两种,同步和异步。

4-5 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

同步使用 XMLHttpRequest对象按照下面模式,可以同步地 XMLHttpRequest对象:1. 创建对象;2. 创建请求;3. 发送请求。

这种模式与传统模式没有区别,用处不大,真正强大的地方在于异步地使用它。

4-6 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

异步使用 XMLHttpRequest对象异步使用 XMLHttpRequest对象时,必须使用 onreadystatech

ange事件调用该对象。在触发该事件后,必须在应用程序采取行动之前检查 readyState属性的内容,因此使用模式应该是:1. 创建该对象;2. 设置 readystatechange事件触发一个指定的函数;3. 检查 readyState属性,看数据是否准备就绪。

如果没有准备好,隔一段时间再次检查。因为数据没有下载完时,我们无法使用它的属性和方法。

如果已经准备好,就继续往下执行;4. 打开请求;5. 发送请求。

readystatechange事件的整个操作都是在后台执行,这样就能够异步使用 XMLHttpRequest对象。

4-7 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

readyState属性readyState属性指出了 XMLHttpRequest对象在发送 /接

收数据过程中所处的几个状态。 XMLHttpRequest对象会经历 5

种不同的状态。 0:未初始化。对象已经创建,但还未初始化,即还没调用 op

en方法; 1:已打开。对象已经创建并初始化,但还未调用 send方法; 2:已发送。已经调用 send 方法,但该对象正在等待状态码和头的返回;

3:正在接收。已经接收了部分数据,但还不能使用该对象的属性和方法,因为状态和响应头不完整;

4:已加载。所有数据接收完毕

4-8 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

XMLHttpRequest对象的属性和方法

XMLHttpRequest对象的属性

属性 说明

Onreadystatechange 返回或设置异步请求的事件处理程序

readyState 返回状态码: 0:未初始化; 1:打开; 2:发送; 3:正在接收; 4:已加载

responseBody(仅 IE7) 使用无符号字节数组返回 HTTP响应

responseText 使用字符串返回 HTTP响应

responseXML 使用 XML DOM对象返回 HTTP响应

Status 返回 HTTP状态码

statusText 返回描述特定 HTTP状态码含义的文本

4-9 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

XMLHttpRequest对象的方法

方法 说明

Abort 取消请求

getAllResponseHeaders 获取 HTTP响应头的整个列表

getResponseHeader 仅获取指定的 HTTP响应头

Open 需要使用多个参数,第一个设置方法属性,第二个设置目标 URL,第三个指定是同步 (false)还是异步 (true)发送请求

Send 发送请求到服务器

setRequestHeader 添加自定义 HTTP头到请求

4-10 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

使用 XMLHttpRequest对象示例此示例使用此对象网页的实现动态显示。页面上

有几个链接,分别点击,可以显示不同的文字或图片,或者清除显示的文字或图片。下面是程序:

4-11 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象// index.htm<html><meta http-equiv="Pragma" CONTENT="no-catch"><meta http-equiv="Expires" CONTENT="-1" /><head> <script type="text/javascript" src="XHRequest.js"></script></head><body>Ajax实例展示<table border=0 cellpadding=0 cellspacing=0 style="font-size:10pt;"><tr><td align=center> <table border=0 cellpadding=2 cellspacing=0 style='font-size:10pt;' align=center> <tr> <td><a href="#" onclick ="sendRequest('Contacts');return false;"> 显示联系我们 </a></td> <td><a href="#" onclick ="sendRequest('Calendar');return false;"> 显示日历时间 </a></td> <td><a href="#" onclick ="sendRequest('Adverts');return false;"> 显示广告图片 </a></td> </tr><tr> <td><a href="#" onclick ="sendRequest('delContacts');return false;"> 清除联系我们 </a></td> <td><a href="#" onclick ="sendRequest('delCalendar');return false;"> 清除日历时间 </a></td> <td><a href="#" onclick ="sendRequest('delAdverts');return false;"> 清除广告图片 </a></td> </tr></table></td></tr><tr><td id="box1" height=60></td></tr><tr><td id="box2" height=50></td></tr><tr><td id="box3" height=50></td></tr></table></body></html>

4-12 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象// XHRequest.jsvar xHRObject = false;if (window.XMLHttpRequest) { xHRObject = new XMLHttpRequest();}else if (window.ActiveXObject) { xHRObject = new ActiveXObject("Microsoft.XMLHTTP"); } function sendRequest(data){ if (data=='delContacts') { box1.innerHTML=''; } else if (data=='delCalendar') { box2.innerHTML=''; } else if (data=='delAdverts') { box3.innerHTML=''; } else { var bodyofrequest = getBody(data); xHRObject.open("POST", "display.php", true); xHRObject.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xHRObject.onreadystatechange = getData; xHRObject.send(bodyofrequest); }}function getBody(data){ var argument = "value="; argument += encodeURIComponent(data) return argument;}function getData(){ if (xHRObject.readyState == 4 && xHRObject.status == 200) { var serverText = xHRObject.responseText; if(serverText.indexOf('|' != -1)) { element = serverText.split('|'); document.getElementById(element[0]).innerHTML = element[1]; } }}

4-13 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象<?php //display.phpswitch($_REQUEST['value']) { case 'Contacts': echo "box1|<br><b>Contacts</b><br>Anhui, Hefei,USTC"; break; case 'Calendar': $dt = gmdate("M d Y H:i:s"); echo "box2|<br><b>Calendar:</b><br> $dt"; break; case 'Adverts': $source = "logo.gif"; echo "box3|<br><b>Advert:</b><br><img src='$source '>"; break; case 'delContacts': echo "box1| "; break; case 'delCalendar': echo "box2|&nbsp;"; break; case 'delAdverts': echo "box3|&nbsp;"; break; }?>

4-14 中国科大《 Ajax编程技术》

4.2 创建 XMLHttpRequest 对象

程序运行:运行初始状态入图 1,点击链接后见图 2:

图 1 图 2

4-15 中国科大《 Ajax编程技术》

4.3 常见错误

编程常见错误 企图通过双击网页文件运行它; XMLHttpRequest大小写不正确;多写了对圆括号:正确: xHRObject.onreadystatechange =getData;

错误: xHRObject.onreadystatechange =getData();

必须弄清楚,在 JavaScript中:函数名后如果有圆括号,意思就是将函数的返回值赋

给等号左边的变量;没有圆括号,是将函数本身赋给等号前的变量。

4-16 中国科大《 Ajax编程技术》

4.3 常见错误

同源问题XMLHttpRequest对象有些问题来自于同源问题。在较早

版本的浏览器中,可以运行来自任何源的任何脚本,由此带来很严重的安全隐患。因此,处于安全的考量,“同源策略”被要求强制执行。即只有来自同一域、同一协议和同一端口的脚本才可以运行。

IE不检验它从 XMLHttpRequest对象中取回的字段。其中的一个字段就是 HTTPREFERER,它包含用户所浏览页面的 URL

/ 域名 (注意:该字段的值并不总是一个 )。这意味着 Referer完全可以在客户端进行伪造。 IE这个的

这个安全漏洞 Referer 值不可信。解决的办法之一是,我们可以在编写 Cookie时,将域名 /服务器添加到 cookie中,以便验证发出的和接收的同源。

4-17 中国科大《 Ajax编程技术》

4.3 常见错误

缓存控制: IE主动缓存为了节约带宽资源,浏览器会在本地缓存页面,

然后从缓存中找出该页面而不是从源服务器下载页面。这样一来,当页面更新后,可能页面并没有显示

这种更新。解决的办法是,强制停止缓存。可以在网页中插入如下代码:

<meta http-equiv=“Pragma” CONTENT=“no-catch” />

<meta http-equiv=“Expires” CONTENT=“-1” />

这样足以使浏览器重载该页面。但如果使用 XMLHttpRequest对象,且请求中包含 GET指令,那么 IE将始终缓存该页面,而决不会重载该页面。

4-18 中国科大《 Ajax编程技术》

4.3 常见错误

缓存问题的解决方法我们有三种办法来解决缓存造成的问题。

1. 在 GET请求后添加 querystring,并确保每次运行时, querystring 值都不一样。将日期作为 querystring

值是一个好主意:xHRObject.open(“GET”,”display.php?id=“ + Number(new Date)+”&value=“ + data, tru

e);

这种“每次输入不同的 querystring 值”的解决方法,从原理上将是一种回避策略。

4-19 中国科大《 Ajax编程技术》

4.3 常见错误

2. 设置 HTTP头部的 If-Modified-Since为一个过期的时间:xHRObject.open=(“GET”, “display.php?value=“+data, true);

xHRObject.setRequestHeader(“If-Modified-Since”, “Sat,1, Jan 2000 00:00:00 GMT”);

使用这种方法,可以阻止缓存。3. 使用 POST 请求。我们将在下一节讨论这种方法。

一般来说,前两种方法用起来比较顺手,第 3种方法可以完全避免缓存的困扰。

4-20 中国科大《 Ajax编程技术》

4.3 常见错误

跨浏览器兼容在使用 Ajax技术时,最困难的问题是让应用程序在不同的

浏览器中都能够正常运行。实际上,这种想法非常不实际。爱 XMLHttpRequest应用中,用户使用的是 IE还是Mozil

la浏览器已成为次要问题,主要问题是创建哪个版本浏览器的 XM

LHttpRequest对象。我们需要注意以下问题: ActiveX控件不能使用在 IE之外的浏览器中; 动态 HTTPjihe document.all 只能在 IE上工作; 在某些版本的 Firefox上运行 XMLHttpRequest会崩溃; IE不区别大小写,而Mozilla 却区别大小写; 不同的 IE 版本,必须调用不同版本的MSXML。 …

4-21 中国科大《 Ajax编程技术》

4.4 POST 方法

使用 POST方法替代 GET方法,是另一种解决 I

E主动缓存页面的办法,它使 Ajax技术提供一个更加无缝的前端。

将 GET方法变成 POST方法,除了需要做:将 querystring 删除;对发送的数据编码;将它作为跨服务器参数发送给 send方法。该参数仍

然是名 / 值,与 querystring 类似,格式为: value=

Contents。但不附加在 URL中,而是使用 URL 编码。

4-22 中国科大《 Ajax编程技术》

4.4 POST 方法

如 4.2节的示例中的 POST方法:function sendRequest(data)

{ if (data=='delContacts') { box1.innerHTML=''; }

else if (data=='delCalendar') { box2.innerHTML=''; }

else if (data=='delAdverts') { box3.innerHTML=''; }

else { var bodyofrequest = getBody(data);

xHRObject.open(“POST”, “display.php”, true); //GET 变为 POST,删除 querystring 参数

xHRObject.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xHRObject.onreadystatechange = getData;

xHRObject.send(bodyofrequest);

}

}

function getBody(data)

{ var argument = "value=";

argument += encodeURIComponent(data) //上传的数据编码,但变量名不编码 return argument;

}

4-23 中国科大《 Ajax编程技术》

4.4 POST 方法

POST方法和 GET方法的比较 POST方法比 GET方法传递的信息量大,最多可达 2GB,而

GET方法则大为减小, IE 限制为 2083个字符, Opera为 405

0个字符, Netscape4为 8192个字符 GET方法只能使用 ASCII码传送且有缓存的困扰;而 POST使用编码传送,且没有缓存的困扰。

如何选则 当查询的结果不会导致客户端页面变化,或下载量较小,使用

GET方法; 当查询的结果会导致客户端页面变化,或下载量很大时,用 PO

ST方法。

4-24 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

I. 动态脚本加载可以用另一种不错的方法来替代 XMLHttpReq

uest对象的使用。这就是动态脚本加载技术。利用此技术,可以使用 DOM动态创建 JavaSc

ript脚本, SRC属性也可以动态赋值。 JavaScript源文件只在将其添加到页面时才下载并执行。

概念:1. 添加脚本到页面;2. 该脚本动态添加到另一个脚本到页面,并在后面附加 SRC属性;

3. 脚本使用服务器启动对话框

4-25 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

示例示例中使用了一个脚本,根据用户选择,动态地

创建其它 3个脚本中的一个。为了简捷,我们不使用服务器启动任何对话框,

因为后面会介绍这种方法还有一些不足。

4-26 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

1. 创建一个名为 ScriptLoader.htm的 HTML页面:

// ScriptLoader.htm

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<script type="text/javascript" src="ScriptLoader.js"></script>

</head>

<body>

你想加载哪个脚本 ?<br/>

脚本 1<input id="range“ name="range" value="1" type="radio" onclick="retrieveInfo('1')" /><br/>

脚本 2<input id="Radio1" name="range" value="2" type="radio" onclick="retrieveInfo('2')" /><br/>

脚本 3<input id="Radio2" name="range" value="3" type="radio" onclick="retrieveInfo('3')"/><br/>

</body>

</html>

4-27 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

2. 创建名为 ScriptLoader.js的脚本:

// ScriptLoader.js

function retrieveInfo(data)

{ var newScript = document.createElement("script");

newScript.src = "script" + data + ".js";

document.body.appendChild(newScript);

}

4-28 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

3. 分别创建 3个脚本,名为 Script1.js, Script2.js, Scrip

t3.js

//Script1.jsalert ("加载了脚本 1");

//Script2.jsalert ("加载了脚本 2");

//Script3.jsalert (“这是脚本 3");

4-29 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

4. 现在运行 ScriptLoader.htm文件,单击第二个按钮,程序运行结果如下图所示:

4-30 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

5. 说明程序关键语句如下:var newScript = document.createElement(“script”); // 创建 Script 元素newScript.src = “script” + data + “.js”; // 设置 SRC 属性document.body.appendChild(newScript); // 将新元素附加在 body 元素

4-31 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

评价 优点:

1. 可以使用多个不同的脚本,并按需加载不同的脚本;

2. 为我们提供了另一个创建服务器调用的机会。 缺点:

1. IE中动态加载脚本会停止其他所有的处理;2. 只能使用 GET方法,不能使用 POST方法;3. 往往不知道脚本是否得到真正的加载。

4-32 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

II. 图象和 cookie

工作方式这种模式的工作方式如下:① <img> 元素使用 src属性封装请求,传递附加在 q

uerystring后的任何其他信息;② 服务器存储该信息,并编写存储在客户端 cookie

中的唯一可识别信息。这种模式与动态脚本加载示例非常相似。但是

没有动态脚本加载的缺点,它被广泛用于拥有大量电子邮件的用户,或者希望跟踪用户浏览习惯的网站。

4-33 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

示例网上售书页面。当用户查看该页面时,其正在浏

览的页面的相关信息会作为图象的一部分发送到服务器,然后服务器会编写唯一的表示符到 cookie,并使用消息框向用户显示该 cookie中包含的信息。

4-34 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

1. 创建 Cataloque.htm

<html xmlns="http://www.w3.org/1999/xhtml" >

<head>

<script type="text/javascript" src="ImageLoader.js"></script>

</head>

<body onload="createImage()" style="font-size:10pt;">

<b>Book:</b><br/>

<img id="cover" src="ajax.jpg" />

<br /><br />

<b>作者 : </b><span id="authors"> 许富 </span>

<br /><b>ISBN: </b><span id="ISBN">97-7-123456</span>

<br /><b>定价 : </b><span id="price">50.20 元 </span>

<img id="secret" src="onebyone.gif" /><br /><br />

<input type="button" onclick="showCookie()" value="查看 cookie" />

</body>

</html>

4-35 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

2. 创建 ImageLoader.js脚本:function createImage(){ var bookid = document.getElementById("ISBN").innerHTML; var img = document.getElementById("secret"); img.src = "relayInfo.php?bookid=" + bookid; img.width = 0; img.height = 0;}

function showCookie(){ var cookie = getCookieInfo("AnonymousID"); alert(cookie);}

function getCookieInfo(cookie){ RegularXp = "(?:; )?" + cookie + "=([^;]*);?"; var RegularXpExtract = new RegExp(RegularXp); if (RegularXpExtract.test(document.cookie)) { return decodeURIComponent(RegExp["$1"]); } else { return null; }}

4-36 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

3. 创建 relayInfo.php:

<?php

if ($_COOKIE[AnonymousID])

{ $tempCookie = $_COOKIE["AnonymousID"];

setcookie("AnonymousID", $tempCookie."|BOOKID:".$_GET["bookid"], time()+3600);

}

else

{ $random_id = (rand()%9999999);

$tempCookie = "USERID:" .$random_id."|BOOKID:" . $_GET["bookid"];

setcookie("AnonymousID", $tempCookie."|BOOKID:".$_GET["bookid"], time()+3600);

}

?>

4-37 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

4. 运行结果 打开浏览器,运行首文件 Cataloque.htm, 见右图。 点击“查看 cookie”,屏幕出现对话框,显示Cookie信息 关闭浏览器,再次打开, cookie信息被追加。

4-38 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

5. 示例说明本例展示出,如何通过动态改变图象的 scr属性来调用服务器。 在页面的开始部分加载了 createImage,然后找到包含该图

书 ISBN的 <span> 元素中的内容(该书内容被存储在 cooki

e中),以及 Ajax.jpg图片var bookid = document.getElementById(“ISBN”).innerHTM

L;var img = document.getElementById(“secret”);

接着,使用指向服务器端页面和作为 querystring传递的图书ISBN替换掉 src属性。

img.src = "relayInformation.php?bookid=" + bookid;img.width = 0;img.height = 0;

4-39 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

服务器端代码仅用来检查 cookie是否存在。如果不存在 cookie,则添加一个唯一的 ID (本例中是一个随机数)和图书的 ISBN号;如果存在 cookie,则在 cookie 尾部添加上述信息。

if ($_COOKIE[AnonymousID]) { $tempCookie = $_COOKIE["AnonymousID"]; setcookie("AnonymousID", $tempCookie."|BOOKID:".$_GET["bookid"], time()+3600); } else { $random_id = (rand()%9999999); $tempCookie = "USERID:" .$random_id."|BOOKID:" . $_GET["bookid"]; setcookie("AnonymousID", $tempCookie."|BOOKID:".$_GET["bookid"], time()+3600); }

4-40 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

然后使用 showCookie()函数显示内容。在这里, A

jax技术快速得到匿名用户的查看模式。所以,利用该 ID 存储数据没有问题,然后就可以慢慢收集用户浏览习惯。

4-41 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

评价 缺点:

如果用户选择关闭图片下载,就没法运行;Cookie 存储信息有限制,大约是 4KB;只能使用 GET方法,不能使用 POST方法。

4-42 中国科大《 Ajax编程技术》

4.5 其他 Ajax 技术

III. 隐藏框架 原理:常使用此技术用于返回服务器信息。它采用

带有两个框架的标准框架,打开两个独立的页面,第一个页面可见,第二个页面宽度和高度设置为 0

而变成隐藏不可见。隐藏框架用于发送请求和接收来自服务器的响应数据,但只在需要时才将接收的数据放在可见的框架中显示。