星期五, 九月 24, 2004

B/S开发的新里程碑(B/S application Milestone)XMLHttpRequest

Dynamic HTML and XML: The XMLHttpRequest Object
动态HTML及XML:介绍XMLHttpRequest对象
(翻译:有增删:原文见:TaH Website
随着XML数据和Web服务的部署越来越普遍,你偶尔会觉的如果在HTML表现层不需要刷新页面而直接
得到XML数据来更新中间状态也是非常方便的.要感谢可爱的 XMLHttpRequest对象,可以在后台直接
提交或获得XML 数据,这扩展了Web Client的使用范围.
为了改变接受到的XML 数据并渲染成HTML内容,依赖于客户端DOM读取XML文档节点树组成用户最终
看见的HTML元素

历史和支持

Microsoft首先在IE 5 window版本用ActiveX技术实现了XMLHttpRequest对象.Mozilla 项目的工程
师们实现了兼容的本地版本Mozilla 1.0(及Netscape 7).Apple在Safari 1.2上完成了同样的工作.

包含W3C标准期望的相似的功能,DOM level 3载入及保存规范.同时随着支持XMLHttpRequest对象意味着这已经成为事实的标准.以后W3C的规范最终应该会支持它并且所有的browser都会支持的。

如何建立对象?

建立一个XMLHttpRequest对象要求根据不同的Browser用不同的方式来实例化对象.对Safari和
Mozila系列.简单调用对象的constructor功能就可以完成这个:
var req = new XMLHttpRequest();

对使用ActiveX的对象,通过传递对象名称来建立:
var req = new ActiveXObject("Microsoft.XMLHTTP");
两种构造方法都返回一个抽象对象的引用.它的方法控制所有的操作,同时他的属性从服务器返回的数据

对象方法

XMLHttpRequest对象在所有支持的环境中使用都非常简明,但是非常强大,列表所有的方法和属性

Table 1显示Safari 1.2,Mozilla及IE 5及以后的windows版本.

Table 1. 一般XMLHttpRequest对象方法







方法描述
abort() 停止当前请求
getAllResponseHeaders()返回一组标题头(标识及其值)字符串
getResponseHeader("headerLabel")返回指定头标识的字符串值
open("method", "URL"[, asyncFlag[, "userName"[, "password"]]])给一个等待状态的请求制定目标URL,方法及其它可选的属性
send(content)发送请求,另外可以附加提交的字符传或DOM对象数据
setRequestHeader("label", "value")跟随请求设定指顶的标题标识及其值.


在Table 1中显示的方法.open()和send()方法可能是你最常用的.
首先open(),用来设置一个将要用的操作场景.两个必须的参数是你将要请求的HTTP方法和连接的目
的URL.对于method参数,你可以设置"GET"接受基本数据.然后使用"POST"发送数据到服务器,尤其是数据可能大于512字节.URL可以是绝对或相对地址(不过可能引起Browser安全问题)

重要的第三个选项参数是Boolean值用来控制是否将来的事物是否异步.默认的行为是true既异步,
这表示脚本进程在调用send()后立即返回不要等待回应.如果你设置这个值为false,那么,脚本将等
到服务器返回数据为止.看起来似乎等待服务器返回数据再继续脚本进程是个好主意.但是这样做可能导致脚本因为网络或服务器问题而不能完成事务,导致脚本挂死.一个安全的主意是用send 异步操作方式,但把代码挂在onreadstatechange事件上是个好主意.
如下例:
var req;

function loadXMLDoc(url) {
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
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 = processReqChange;
req.open("GET", url, true);
req.send();
}
}
}

注意:从服务器返回的数据必须保证Content-Type是:text/xml 内容设置为text/plain或text/html
不被request对象接受.

对象属性

Table 2. 所有属性都是只读的
Table 2. 常见 XMLHttpRequest对象属性










属性说明
onreadystatechange当每个状态改变时产生的事件
ReadyState对象状态整数0 = uninitialized1 = loading2 = loaded3 = interactive4 = complete
responseText服务器返回结果的字符串样本
responseXMLDOM规范的服务器返回结果
status Numericcode returned by server, such as 404 for "Not Found" or 200 for "OK"
statusTextString message accompanying the status code


使用onreadystatechang属性用来挂上函数来出去request对象状态改变事件.这样当对象状态改变的时候,就会调用函数处理.
你必须使用更多信息来确定挂上的回掉函数如何处理信息.判断readstate是多少或通过判断status或statusText来确定过程是成功或失败.成功为200或ok.

通过responseText或responseXML来处理服务器返回的结果
如下:
function processReqChange() {
// only if req shows "loaded"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
// ...processing statements go here...
} else {
alert("There was a problem retrieving the XML data:\n" +
req.statusText);
}
}
}

如果你关心timeout的服务器问题.你可以修改上面的loadXMLDoc函数保留处理时间戳.当超过可接受 限制的时候,调用abort()函数来放弃操作,然后给出警告既可.

安全问题

当在browser使用XMLHttpRequest对象时候,默认采用同一domain的安全规则.(共享同一"沙盒")
这会引起重要的安全问题.

大多数browser支持通过http:协议来访问需要接受的对象.这意味着你不能使用在本地硬盘的测试页面.实际上,Mozilla要求你包装UniversalBrowserRead安全权限.而IE简单显示一个安全警告框,给你一个取消的机会.
以下是Mozilla包装安全授权的代码:
try
{
http.open("GET", "http://wang.journalspace.com", true);
}catch(e)
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
http.open("GET", "http://wang.journalspace.com", true);
http.onreadystatechange=function() {
if (http.readyState==4) {
alert(http.responseText);
document.getElementById('content').innerHTML=http.responseText;
}



许多年来,高级客户段开发人员经常想用一种清晰的方法来维护同服务器之间的"Connection".
这样能保证事务发生在后台.许多技术要求使用自刷新的frame或无脸的java applet技术.
在W3C标准依然在开发的时候.Microsft的XMLHttpRequest对象填充了这一空白,将鼓舞应用开发的
创新.