现在的位置: 首页 > 综合 > 正文

XMLHttpRequest对象

2013年11月11日 ⁄ 综合 ⁄ 共 6142字 ⁄ 字号 评论关闭

通过上节的分析,我们知道Ajax 中向服务器提出请求以及截获响应的功能都是通过XMLHttpRequest对象实现的。在这一小节中,我们详细的讨论一下该对象的结构及使用。

2.3.1 XMLHttpRequest对象概述
XMLHttpRequest对象是一个和浏览器相关的对象,虽然在不同的浏览器中该对象的叫法不同,但是基本上都可以实现相同或相似的功能。比如,在IE中或基于IE的浏览器中如“傲游”中此功能的对象叫作XMLHttp,而在FireFox中实现此功能的对象就叫作XMLHttpRequst。
2.3.2 XMLHttpRequest对象的结构
在前面的讲解中,我们可以了解到,该对象的基本作于是向服务器发过请求,并且截获服务器的响应流。
1)              向服务器发出请求。使用该对象的Open方法可以指明向哪个服务器发送请求。而利用Send方法可以将请求发出。这两个方法的原型如下:

 

MLHttpRequest.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);
参数
bstrMethod
http方法,例如:POSTGETPUTPROPFIND。大小写不敏感。
bstrUrl
请求的URL地址,可以为绝对地址也可以为相对地址。
varAsync[可选]
布尔型,指定此请求是否为异步方式,默认为true。如果为真,当状态改变时会调用onreadystatechange属性指定的回调函数。
bstrUser[可选]
如果服务器需要验证,此处指定用户名,如果未指定,当服务器需要验证时,会弹出验证窗口。
bstrPassword[可选]
验证信息中的密码部分,如果用户名为空,则此值将被忽略。
下面的例子演示从服务器请求book.xml,并显示其中的book字段。
var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP.3.0");
xmlhttp.open("GET","http://localhost/books.xml", false);
xmlhttp.send();
var book = xmlhttp.responseXML.selectSingleNode("//book[@id='bk101']"); alert(book.xml);
备注
调用此方法后,可以调用send方法向服务器发送数据。
 
XMLHttpRequest.send(varBody);
参数
varBody 
欲通过此请求发送的数据。
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP.3.0");
xmlhttp.open("GET", "http://localhost/sample.xml", false);
xmlhttp.send();
alert(xmlhttp.responseXML.xml);
备注
此方法的同步或异步方式取决于open方法中的bAsync参数,如果bAsync == False,此方法将会等待请求完成或者超时时才会返回,如果bAsync == True,此方法将立即返回。
This method takes one optional parameter, which is the requestBody to use. The acceptable VARIANT input types are BSTR, SAFEARRAY of UI1 (unsigned bytes), IDispatch to an XML Document Object Model (DOM) object, and IStream *. You can use only chunked encoding (for sending) when sending IStream * input types. The component automatically sets the Content-Length header for all but IStream * input types.
如果发送的数据为BSTR,则回应被编码为utf-8, 必须在适当位置设置一个包含charset的文档类型头。
If the input type is a SAFEARRAY of UI1, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.
如果发送的数据为XML DOM object,则回应将被编码为在xml文档中声明的编码,如果在xml文档中没有声明编码,则使用默认的UTF-8
If the input type is an IStream *, the response is sent as is without additional encoding. The caller must set a Content-Type header with the appropriate content type.
 

 

 

 
 2)              获取服务器的响应流。
由于服务器的响应流是在服务器处理完数据之后再返回客户端的,因此,该对象是无法直接主动获取响应流的。这里是通过事件通知机制来处理响应流的返回值的。要想实现此功能,首先,要在Ajax引擎中(Javascript代码中)编写一个函数,然后将XMLHttpRequest对象的onreadystatechange属性的值设置为前面编写的那个函数的名。这时,如果服务器的响应返回的话,就会在前面指定的那个函数里进行处理。
另外,由于我们不能保证每一次客户端的请求都是成功的,所以,开发人员一定要在前面设置的函数里判断一下,返回的Http状态码。我们可以通过XMLHttpRequest对象的status属性来获取该状态代码,状态代码意义如下:
100
Continue
101
Switching protocols
200
OK
201
Created
202
Accepted
203
Non-Authoritative Information
204
No Content
205
Reset Content
206
Partial Content
300
Multiple Choices
301
Moved Permanently
302
Found
303
See Other
304
Not Modified
305
Use Proxy
307
Temporary Redirect
400
Bad Request
401
Unauthorized
402
Payment Required
403
Forbidden
404
Not Found
405
Method Not Allowed
406
Not Acceptable
407
Proxy Authentication Required
408
Request Timeout
409
Conflict
410
Gone
411
Length Required
412
Precondition Failed
413
Request Entity Too Large
414
Request-URI Too Long
415
Unsupported Media Type
416
Requested Range Not Suitable
417
Expectation Failed
500
Internal Server Error
501
Not Implemented
502
Bad Gateway
503
Service Unavailable
504
Gateway Timeout
505
HTTP Version Not Supported

大多数情况下,开发人员并不需要关心所的状态,一般只关心返回的状态是不是“OK”状态即可,这时只要判断XMLHttpRequest对象的status属性的值是否为200即可。

除此之外,当客户端向服务器发出一个请求之后,服务器会向客户端作出五次响应,并且每一次响应都会被客户端所获取。这五次服务器响应代表了返回XMLHTTP请求的当前状态,我们可以通过XMLHttpRequest对象的readyState属性来获取该状态代码。状态代码代表示的意义如下:

0 (未初始化)
对象已建立,但是尚未初始化(尚未调用open方法)
1 (初始化)
对象已建立,尚未调用send方法
2 (发送数据)
send方法已调用,但是当前的状态及http头未知
3 (数据传送中)
已接收部分数据,因为响应及http头不全,这时通过responseBodyresponseText获取部分数据会出现错误,
4 (完成)
数据接收完毕,此时可以通过通过responseBodyresponseText获取完整的回应数据
大多数情况下,开发人员并不需要关心所的状态,一般只关心返回的状态是不是“完成”状态即可,这时只要判断XMLHttpRequest对象的readyState属性的值是否为4.
如果上面的各种状态都能符合我们的要求,那么最后要作的就是将该响应流中的数据提取出来,我们可以使用XMLHttpRequest对象中的以下三个属性来获取数据,这三个属性用来表达数据的不同形式。
responseBody返回某一格式的服务器响应数据。
变量,此属性只读,以unsigned array格式表示直接从服务器返回的未经解码的二进制数据。
responseStreamAdo Stream对象的形式返回响应信息
变量,此属性只读,以Ado Stream对象的形式返回响应信息。
responseText将响应信息作为字符串返回
变量,此属性只读,将响应信息作为字符串返回。
XMLHTTP尝试将响应信息解码为Unicode字符串,XMLHTTP默认将响应数据的编码定为UTF-8,如果服务器返回的数据带BOM(byte-order mark),XMLHTTP可以解码任何UCS-2 (big or little endian)或者UCS-4 数据。注意,如果服务器返回的是xml文档,此属性并不处理xml文档中的编码声明。你需要使用
responseXML来处理。
responseXML将响应信息格式化为Xml Document对象并返回
变量,此属性只读,将响应信息格式化为Xml Document对象并返回。如果响应数据不是有效的XML文档,此属性本身不返回XMLDOMParseError,可以通过处理过的DOMDocument对象获取错误信息。
2.3.3          使用XMLHttpRequest对象与服务器交互
前面讲解了XMLHttpRequest对象的基本结构,下面我们将利用所学的内容来实现一个简单Ajax引擎。
实例需求:
利用Ajax技术实现一个页面不刷新的,并且验证一个用户名是否被注册过的过程。
要求:
在页面中添加一个文本框标签用于输入用户名,添加一个按钮用于提交用户数据。验证的结果被直接打印在页面上。
操作步骤如下:
1)打开Visual Studio(笔者使用的是Visual Studio2008 Beta2,因为VS2008在页面的布局方面更好控制),建立一个网站,如图2-5所示。
图2-5新建立一个网站
项目建立好之后,大家会看到VS2008中基本上已经将Express Web的功能集成,可以将HTML的设计视图和HTML的代码进行上下分开显示。如图2-6所示。
图2-6 VS2008的编辑窗口
2)在VS2008工具箱的HTML栏中添加一个 控件及 控件。如图2-7所示。
图2-7 添加表单控件
3) 在<Head></Head>中加入<script type ="text/javascript"></script>标签,以便进行Ajax引擎的编写,并在基本定义一个XMLHttpRequest对象,但是并不进行初始化操作。如图2-8所示。
2-8 添加新标签
3)定义两个函数Validation()及OnMessageBack(),前者用于初始化XMLHttpRequest对象,后者则在服务器的数据返回被调用。在Validation()函数中加入如下Javascript代码:
//实例化XMLHttpRequest对象
        xmlhttp =new ActiveXObject ("Microsoft.XMLHTTP");
        //找到名为Text1的文本框
        var name=document .getElementById ("Text1");
        //利用Open方法向指定URL
        //查询字符串name将文本框中的数据传送到目标页面
        xmlhttp .open("Post","default.aspx?name="+name.value);
        //设置当服务器响应返回时用于处理响应的函数名
        xmlhttp .onreadystatechange=OnMessageBack;
        //送发请求
        xmlhttp .send(null);
代码添加完毕后,Html页面内容如图2-9所示。
图2-9 添加代码
4)添加OnMessageBack()函数的内容。代码如下:
function OnMessageBack()
    {
        //判断请求状态及HTTP状态是否都能满足条件
        if (xmlhttp .readystate==4&&xmlhttp .status==200)
        {
            //将返回的文本打印到页面上
            document .write (xmlhttp .responsetext);
        }
    }
代码添加完毕后,Html页面内容如图2-9所示。
图2-10添加代码
5) 下面为Button1添加事件代码,将其标签修改为
<input id="Button1" type="button" onclick ="Validation()" value="button" />
6)页面中的Ajax引擎已经编写完毕。在图2-10所示的第18行代码中,大家可以看到该用户名是通过一个名为“name”的查询字符串进行传递的,该查询字符串传递到服务器后需要进行后台处理,因此,要对“Default.aspx.cs”中的Page_Load方法添加一些ADO.NET代码。这里的数据库使用的是“Northwind”示例数据库。如图2-11所示。
2-11 后台C#代码
这里要注意,当服务器利用Response.Write()方法向客户端发出响应后,客户端的Ajax引擎就截获该响应流,并在我们事先定义的“OnMessageBack()”方法中进行处理。
7)下面按F5进行调试。在文本框中输入“ALFKI”,点击按钮,页面中会显示“该用户名已经被占用,请使用其他用户名!”,如图2-12所示。
2-12 测试一
再在文本框中输入一个用户名“ABC”,会显示“该用户名可以使用”,如图2-13所示。
2-13 测试二

但是,在第二次测试时,大家会奇怪的发现页面出现了两组相同的表单。这是因为我们目前还没有使用DOM模型对页面进行控制,该问题的解决方案会在后面章节中进行说明。

抱歉!评论已关闭.