主讲教师:李艺[email protected] ajax 编程技术 第四章 ajax 技术. 中国科大《 ajax...
Post on 19-Dec-2015
313 views
TRANSCRIPT
主讲教师:李艺主讲教师:李艺[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| "; break; case 'delAdverts': echo "box3| "; 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
而变成隐藏不可见。隐藏框架用于发送请求和接收来自服务器的响应数据,但只在需要时才将接收的数据放在可见的框架中显示。