鸟食轩

 Microsoft .NET[C#] MVP 2003
随笔 - 429, 文章 - 235, 评论 - 5527, 引用 - 356
数据加载中……

使用XMLHTTP Request Object获取服务器数据

    在Web客户端使用xmlhttp对象,可以十分方便的和服务器交换数据,我们可以获取和发送任何类型的数据,甚至二进制数据到服务器上。xmlhttp技术同时也是目前大多数无刷新页面使用的和服务器交换数据的方式,这种方式比以往的隐藏iframe的方法要方便和经济的多。

    同时让我们高兴得是xmlhttp并不是IE特有的东西,虽然目前还不是W3C的标准,不过IE, Netscape/Mozilla, 和Safari都支持。在IE中我们使用new ActiveXObject('MSXML2.XMLHTTP')或者new ActiveXObject("Microsoft.XMLHTTP")来获得的xmlhttp对象实例,使用前者还是后者和客户端机器安装的MSXML版本有关。在Netscape/Mozilla和Safari中,使用new XMLHttpRequest()来获得xmlhttp对象实例。比如在IE中,我们通常这样使用:

var xmlhttp = null
try 

    xmlhttp 
= new ActiveXObject("MSXML2.XMLHTTP"); 

catch(e) 

    
try 
    { 
        xmlhttp 
= new ActiveXObject("Microsoft.XMLHTTP"); 
    } 
    
catch(e2){} 


    使用xmlhttp对象其实是并不是什么困难的事,它一共就6个方法8个属性。不过它最主要的是提供了两种执行模式:同步模式和异步模式。同步模式可以比较精确的控制程序流程,可是如果服务器的Response太慢,browser会有死掉失去相应的问题;而使用异步模式由于是事件触发方式控制流程,会给程序运行带来一些不可与预计的问题,因为你不知道客户端等待服务器Response的过程中,用户会在browser里做什么操作。 

    下面是一个同步方式获取服务器数据的简单示例:

function GetRemoteData(url)
{
    
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    
try
    {  
         xmlhttp.open('GET', url, 
false);
         
if ( xmlhttp.status == 200 )
         {
             
return xmlhttp.responseText;
         }
         
throw ''; 
    }
    
catch(e)
    {
         
return '';
    }
}


    XMLHTTP对象的属性和方法列表(来自IXMLHTTPRequest接口):
   
Name Type Description
onreadystatechange N/A 指定当就绪状态发生改变时调用的事件处理函数,仅用于异步操作 
readyState Long 异步操作的状态:未初始化(0),正在加载(1),已加载(2),交互(3),已完成(4)
responseBody Variant 将响应信息正文作为unsigned byte数组返回
responseStream Variant 将响应信息正文作为一个ADO Stream对象返回
responseText String 将响应信息正文作为一个文本字符串返回
responseXML Object 通过XMLDom将响应信息正文解析为XMLDocument对象
status Long 服务器返回的HTTP状态码
statusText String 服务器HTTP响应行状态
   
Name Desciption
abort 取消当前 HTTP 请求
getAllResponseHeaders 从响应信息中检索所有的标头字段
getResponseHeader 从响应信息正文中获得一个 HTTP 标头值
open(method, url, boolAsync, bstrUser, bstrPassword) 打开一个与 HTTP 服务器的连接
send(varBody) 设定一个请求的标头字段
setRequestHeader(bstrHeader, bstrValue) 向 HTTP 服务器发送请求。可包含正文。

    这里面显然就open方法比较麻烦,带了一大堆参数,它们的含义分别是:
   
Parameter Description
method HTTP的通信方式,比如GET, HEAD, POST, PUT, DELETE, CONNECT等
url 接收数据的服务器的URL地址,URL可带QueryString
boolAsync 一个布尔标识,说明请求是否为异步的。如果是异步通信方式,客户端就不等待服务器的响应;如果是同步方式,客户机会等到服务器返回消息后才去执行其它操作
bstrUser 用户ID,用于服务器身份验证
bstrPassword 用户密码,用于服务器身份验证

    异步通讯的示例:

xmlhttp.open("GET""default.aspx"true);
xmlhttp.onreadystatechange 
= function()
{
    
if ( xmlhttp.readyState==4 )
    {
        alert(xmlhttp.responseText);
    }
}
xmlhttp.send(
null);


    其实使用xmlhttp就这么简单,复杂的是服务器端数据的组织方式,而且需要开发人员同时熟悉Client和Server端的开发,才能事半功倍。可是好像说了半天这个玩意儿和xml没有什么关系啊,怎么叫xmlhttp呢?我们注意到response的数据类型中有一个responseXML,不过它解析返回的XMLDocument属于XMLDOM的内容了,和使用xmlhttp来和服务器通讯的关系并不大,以后再来细说。

posted on 2004-12-26 22:22 birdshome 阅读(19831) 评论(28)  编辑 收藏 网摘 所属分类: Jscript&Dhtml开发

评论

#1楼   回复  引用    

关于XMLHttp的浏览器兼容性,可以参考一下
http://jibbering.com/2002/4/httprequest.html
2004-12-27 09:07 | bestcomy[未注册用户]

#2楼[楼主]   回复  引用  查看    

那个使用'head'方法比较有意思,这样做类似网络文件管理效率就能保证了。
2004-12-27 20:32 | birdshome      

#3楼[楼主]   回复  引用  查看    

相关文章推荐:构建一个pool来管理无刷新页面的xmlhttp对象
2005-02-07 11:14 | birdshome      

#4楼   回复  引用  查看    

如果使用动态修改document.scripts通过其src动态加载服务器的文件呢?
2005-02-18 21:51 | 辣妹子      

#5楼[楼主]   回复  引用  查看    

xmlhttp最重要的是可以和server端之间透明的处理xml文档,加之可以灵活的选用同步/异步操作,而其还是W3C推荐的东西(不过好像还没有成为标准),为什么还要考虑<script>这种方式呢?
2005-02-18 23:51 | birdshome      

#6楼   回复  引用  查看    

如果以标准来看的话,首先 script是标准,没有哪个浏览器不支持 script (当然我所知道的浏览器也都支持xmlhttp),其次,xmlhttp也是由script加载的,所以script比xmlhttp功能更加强大。

^_^纯属讨论。其实我以前一直用script,现在一直用xmlhttp,但我一直没发现xmlhttpp比script好的地方,唯一好的就是大家都接受。
2005-02-19 05:54 | 辣妹子      

#7楼   回复  引用    

唯一好的就是大家都接受。还有什么比大家都能接受更好的事情呢? :)
2005-02-19 18:43 | birdshome

#8楼   回复  引用    

晕倒,这样也算考虑兼容,连基本的MOZILLA兼容都没考虑
寒啊寒
2005-03-19 00:01 | flashsoft

#9楼   回复  引用    

最近用xmlhttp时遇到个奇怪的问题

一个使用xmlhttp异步进行的操作,大部分人使用起来都是正常的,3、5秒内会完成。但是有几个人的机器在操作时,需要3-5分钟甚至更长时间。

经过跟踪,发现请求提交到服务器,服务器所有操作执行完毕都非常快,大概也就1、2秒的样子,但是却要等待那么长时间才会返回到客户端,不知道是为什么?
也就是客户端在等待readystate状态4的出现,需要很长时间,1、2、3是很快就完成的。
已经完全排除了Windows版本、IE版本、Service Pack安装情况、网络问题等原因。
2005-07-09 16:22 | Richie[未注册用户]

#10楼[楼主]   回复  引用  查看    

@Richie
你说到的"但是有几个人的机器在操作时,需要3-5分钟甚至更长时间。",是说大量并发访问服务器时总是有人会这样,还是说就是几个特定的client会这样呢?
2005-07-09 17:23 | birdshome      

#11楼   回复  引用    

就几个特定的Client每次都是这样,其它Client每次都是正常的。

象Client上机器配置不好、网络状况原因、Windows IE版本和补丁安装状况等,这些原因都有怀疑过,经过实际检查,觉得应当不是这些造成的。因为那几个操作在没有使用xmlhttp方式之前,这些用户使用都是正常的。方式修改了之后,这几个用户一直是这种症状,其它机器从不会出现。
找了台机器,512M的内存,所有补丁都是最新的,内存使用状况良好,网络连接检测一切正常。调试状况下,readystate为4需要好几分钟才出现。

因为经常也看到一些网页,页面已经完全加载完毕,但是IE的状态烂上的进度一直显示没有完成,需要等很长一段时间。是否和这种状况有关,这种状况应当怎样解决?
2005-07-09 23:06 | Richie[未注册用户]

#12楼[楼主]   回复  引用  查看    

@Richie
服务器端用什么的语言?能确定服务器端已成功render吗?
2005-07-09 23:56 | birdshome      

#13楼   回复  引用    

C#,跟踪过服务器端,很快执行完毕
2005-07-10 10:42 | Richie[未注册用户]

#14楼[楼主]   回复  引用  查看    

@Richie
IE是sp1加最新hotfix吗?页面中有没有png图片?
2005-07-10 15:57 | birdshome      

#15楼   回复  引用    

一个使用xmlhttp异步进行的操作,大部分人使用起来都是正常的,3、5秒内会完成。但是有几个人的机器在操作时,需要3-5分钟甚至更长时间。

这个情况我这也有
很奇怪

alert (xmlhttp.readyState);
if (xmlhttp.readyState==4)
{
div_message.innerHTML = xmlhttp.ResponseText;
}

如果不用alert后面都都不执行
用了就正常
但我根本不需要ALERT,这个只是调试用的
2005-08-01 09:09 | 堕落[未注册用户]

#16楼   回复  引用    

alert (xmlhttp.readyState);
为1
2005-08-01 09:11 | 堕落[未注册用户]

#17楼[楼主]   回复  引用  查看    

@堕落
把alert(xmlhttp.readyState)改成赋值语句: var status = xmlhttp.readyState,试试能通过吗?
2005-08-01 10:15 | birdshome      

#18楼   回复  引用    

我取消使用异步了
还有个问题请教
怎么让脚本发送请求到ASP
然后ASP根据请求把有个服务器端文件载入XML节点
在用脚本去接收保存这个文件

简单的说用XML的节点装载文件数据
通过XMLHTTP传送到客户端
再用ADODB.Stream保存文件到客户机
2005-08-02 04:13 | 堕落[未注册用户]

#19楼   回复  引用    

客户端
function downfile()
{
var file=ftp.file.value;
//file=file.replace(/\-/g,"\\");
var path=ftp.path.value;
var temp=file.split("\\");
var name=temp[temp.length-1];
// 把请求发送到Web服务器
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("POST","./ftp_file.asp?action=downs&file="+file+"",false);
xmlhttp.send();
// if (xmlhttp.readyState==4)
// {
//从Response对象创建 XMLDOM对象
var xml_dom = new ActiveXObject("MSXML2.DOMDocument");
xml_dom.load(xmlhttp.ResponseStream);
// alert (xml_dom);
// xml_dom.load(xmlhttp.responseXML);
// xml_dom.load(xmlhttp.responseXML.xml);
//读出包含二进制数据的节点
var xml_file = xml_dom.selectSingleNode("root/file");
// 创建 ADO-stream 对象
var ado_stream = new ActiveXObject("ADODB.Stream");
// 打开Stream对象,接收二进制
ado_stream.Type = 1; // 1=adTypeBinary
ado_stream.Open();
ado_stream.Write(xml_file.nodeTypedValue);
//文件存盘
ado_stream.SaveToFile(path&name,2);
//2=adSaveCreateOverWrite
div_message.innerHTML = "download OK!"
// }
}
2005-08-02 04:15 | 堕落 [未注册用户]

#20楼   回复  引用    

服务器端
sub downfile()
dim xml_dom
dim node
dim ado_stream
'创建包含默认头信息和根节点的 XML文档
' Response.ContentType = "text/xml";
set xml_dom = Server.CreateObject("MSXML2.DOMDocument")
xml_dom.loadXML("<?xml version=""1.0"" ?> <root/>")
' 指定数据类型
xml_dom.documentElement.setAttribute "xmlns:dt", "urn:schemas-microsoft-com:datatypes"
' 创建一个新节点,设置其为二进制数据节点
node = xml_dom.createElement("file")
node.dataType = "bin.base64"
set ado_stream = Server.CreateObject("ADODB.Stream")
' 打开Stream对象,载入文件数据
ado_stream.Type = 1 ' 1=adTypeBinary
ado_stream.open
ado_stream.LoadFromFile(file)
'将文件内容存入XML节点
node.nodeTypedValue = ado_stream.Read(-1)
' 关闭Stream对象
ado_stream.Close()
xml_dom.documentElement.appendChild(node)
' 输出XML
xml_dom.save Response,1
Response.End
xml_dom.Close()
end sub
2005-08-02 04:16 | 堕落 [未注册用户]

#21楼[楼主]   回复  引用  查看    

@堕落
你帖的示例代码中遇到了什么具体问题呢?
2005-08-02 10:20 | birdshome      

#22楼   回复  引用    

那么要失去使用Linux系统的用户了
2006-06-07 10:29 | 不晓得[未注册用户]

#23楼   回复  引用    

这样做的有一个问题:

中文会有乱码,不太好解决

2006-12-01 08:26 | infozero[未注册用户]

#24楼   回复  引用    

好像还是感觉很模糊。
知道是怎么一回事;
还不知道自己到底怎么弄。
2007-09-12 14:44 | aasheaa[未注册用户]

#25楼   回复  引用    

@Richie
这个问题怎么解决的,我也遇到了
2008-04-11 12:10 | flyfly[未注册用户]

#26楼   回复  引用    

非常好哦,正在学XMLHTTP;



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 82238




相关文章:

相关链接: