Ajax无刷新方法纵览(1)—XMLHttpRequest对象
来源:互联网 发布:java实现n! 编辑:程序博客网 时间:2024/05/22 03:24
一.XMLHttpRequest对象
1.XHR对象的调用及其属性和方法
关于无刷新技术,很自然的会想到XMLHttpRequest(XHR)对象,这是Ajax中请求服务器局部刷新的技术基础,在主流的浏览中都支持XHR,不过是在不同版本和类型的浏览器是用不同的方法获取这个对象。
try
{xhr= new ActiveXObject('Msxml2.XMLHTTP'); /*IE5.0*/}
catch(e)
{
try{xhr= new ActiveXObject('Microsoft.XMLHTTP'); /*IE5.5*/}
catch(e)
{
try{xhr= new XMLHttpRequest();/*IE7及其他类型浏览器*/}
catch(e){}
}
}
上面利用异常的机制实现了浏览器的兼容。
XHR有同步和异步两种方式,同步请求时,页面会等待服务器的响应结束才允许用户继续进行其他工作,因此如果这个请求阻塞用户很久,那是很令人失望的。所以,通常使用的是异步请求,让用户可以在等待响应的期间可以继续做其他的。下面是典型的打开一个异步请求并处理的代码。
xhr.onreadystatechange=function() { //注册请求状态改变的处理事件
if(xhr.readyState==4) {
if(xhr.status==200) {
var text=xhr.responseText;
}
}
}
—open()方法是向服务器发送一个请求的前的准备,使用它可以创建一个请求。其完整的形式是open(method,url,asynchronous,username,password),正如上面的示例,后面三个参数是可选的。第三个参数表示请求是否是异步,不设值时,默认的便是true即异步。第一个参数是发送请求的方式,一般是GET或POST比较常用(其他的还有PUT、DELETE等方法)。
- GET方法如果传递参数,是用紧跟在"?"后面用"&"分隔开的名值对,作为查询字符串提交。在服务器端处理时一般用request.querystring提取(PHP用$_GET("参数名"))。由于send方法中参数body是必须的,而GET方法下不发送数据到服务器端,所以可以为null。
- POST方法,实际也是可以在URL中传递查询字符串的,并在服务器端用同样的方法提取。然而使用POST方法,是因为需要发送影响服务器状态或更大量的数据。它发送的数据是send方法中body参数的值,该参数也是查询字符串的形式(这也许比较常见,或者说更容易用标准的方式可以提取,就如同从表单用POST方式提交,而实际上如果不设置请求的头部信息,它可以是任何形式)。在服务器端获取时,一般使用request.form提取(PHP用$_POST("参数名"))需要特别注意的是,由于是CGI风格(表单式的提交)上传浏览器数据,所以需要用setRequestHeader方法设置请求的头部信息,这必须要在send方法前设置。
xhr.open("post","ajax.aspx")
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.onreadystatechange=function() {
if(xmlhttp.readyState==4) {
if(xmlhttp.status==200) {
var text=xhr.responseText;
}
}
}
xhr.send("arg=a&arg=b");
—send()方法发送请求。可以发现为XHR对象上注册了一个onreadystatechange事件处理函数。它使得在send方法发送请求后,请求的状态一但发生改变就会触发这个事件。为了使事件发生时可以被接受处理,因此应该将该事件的处理函数的声明放在send方法的前面。实际上open和send方法都会触发onreadystatechange,然而我们比较关心发送请求后的状态改变因此只在send方法前面声明了处理函数就应该足够了。
(题外话:这似乎让有点不清楚,为什么要在send前面。如果可以明白Javascript是面向对象的语言,那么就会更清楚,这无非是在给成员赋值。用script标签中定义的方法和成员来说明,通常我们可以在JS代码的任何地方直接使用全局的方法或变量。而实际上,任何的在script标签中定义的全局方法或变量都是window类的成员,当浏览器生成window对象后,也可以用"window.方法名或变量名"的方法访问。在页面加载的过程中解释这些全局的成员,实际上是在解析这个window类,不存在定义先后的问题,因为它们在生成window对象后无论定义先后都会成为的对象成员,每一个类的全局成员的调用都是实际上通过"对象.方法名"的方法访问到的,而在上面的XHR对象最开始并不是我们定义的,我们使用第一段代码获得的,它自己定义了如open、send、onreadystatechange、readyState、status这些成员。我们为它定义的onreadystatechange事件处理函数什么时候开始存在,取决于我们在"new XHR对象"声名引用后,什么时候定义的onreadystatechange事件处理的函数。这实际是在给函数的成员赋值,不过是为事件处理函数成员赋了一个匿名函数)
—readyState变量(也可以称为属性)是用于记录下请求的状态。
- 当XHR对象产生时它的状态为0(对象已经建立但还未初始化)。
- open方法执行后状态为1(open已被调用)。
- send方法执行后状态为2(send已被调用)。
- 请求发送成功状态为3(正在接受数据)。
- 请求完成时状态为4(请求完成,返回数据已被接收)。
状态1到3在不同的浏览器中的解释不同,但是我们通常比较关心状态4即请求完成。如果onreadystatechange处理中readyState的值为4就可以继续作请求完成的处理了。
—status属性用于对请求结果的判断。status获得服务器返回的HTTP响应状态编码,表示服务器处理请求结果的状态。这些编码和浏览器正常打开一个页面的响应状态编码一样,包括的404(请求资源未找到)和500(内部服务错误)等,而200(请求成功)在一般的浏览页面响应中就是把页面显示出来不会有其他的,而这里我们需要判断是否响应状态是200,如果是就操作响应返回的结果。
—statusText属性获取响应编码的描述,如" Not Found"等。
—responseText属性获取响应返回的文本,它可以是纯文本或HTML片段。它是接受请求的页面处理完成后,输出到请求页面上的结果内容,这和直接用open方法中的URL参数地址访问请求页面是得到同一结果。
—responseXML属性返回XML文档(DOM)对象,只有当服务器端返回一个XML格式的文档才有效,所以以需要为响应设置头部信息。如果请求的是一个.xml后缀的文件,服务器会自动的设置。否则,需要用代码设置,如response.ContentType="text/xml"。因为获取的是一个DOM模型对象,所以可以用DOM模型进行解析和操作。
—abort()方法取消一个请求,并把请求状态重置为0。
—getAllResponseHeaders()方法,获取包含所有响应头部信息的一个字符串,每个信息之间用换行符号分隔。
—getResponseHeader()方法,获取指定的响应头部信息,接受一个参数,是头部信息字段名称的字符串。
—setRequestHeader()方法,指定请求的头部信息。
*其他的属性和方法
- —responseBody属性(IE6及以下 Olny)获取服务器返回的未经编码的二进制数据,是数组格式。在IE7中已经无法获取该属性。
- —responseStream属性(IE6及以下 Olny)返回AdodbStream对象,是原始编码的数据流,它的编码形式取决于服务器发送的编码形式,可以是二进制、UTF8等。它还可以读取非文本数据,如图象、应用程序等。这个属性只有在IE才被支持,因为它获取的AdodbStream对象是IE中特有的,在IE中是ActiveX对象注册的,在IE7中AdodbStream已经被禁止,IE6及以下可以直接创建。在其他浏览器下会出错。这个AdodbStream可写,并且可以写入文件到客户的主机上,因此有很大安全隐患,许多的木马开始用AdodbStream对象的方法和属性通过浏览器传播木马(FireFox等浏览器没有这类型ActiveX控件,因此很安全)。其实,可以把responseBody中的二进制数据写入到AdodbStream对象中,与直接从responseStream属性获取对象是一样的。如下面的示例: xhr.open(("get","http://website.com/1.exe",true);
xhr.send(null);
var adoStream=new ActiveXObject("ADODB.Stream");
adoStream.Type=1;//数据流类型,1表示二进制
adoStream.Open(); //打开对象
adoStream.write(xhr.responseBody); //写入数据
adoStream.SaveToFile("1.exe",2); //第一参数是保存文件的地址;第二参数是保存的方式,1-如果文件不存在就创建,2-如果文件已存在,用数据流覆盖文件中的数据
adoStream.Close();//关闭对象 - —overrideMimeType()方法(FireFox Only) 是对响应的页面内容以特定编码进行识别。目前,大多数的网页都是UTF8编码。但是,仍然有不少中文网页文件保存使用了GB2312编码,而XHR对像默认的是以UTF8编码识别网页,因此有时访问会产生乱码,FireFox浏览器提供了overrideMimeType方法解决这个问题。 xhr.open("GET", "ajax.aspx");
xhr.overrideMimeType("text/html;charset=gb2312");//以gb2312编码识别数据
xhr.onreadystatechange = function(){
if (xhr.readyState == 4)
if (xhr.status == 200)
var text=xhr.responseText;
};
xhr.send(null);function gb2_To_utf8(data){
var glbEncode = [];
gb2utf8_data = data;
execScript("gb2utf8_data = MidB(gb2utf8_data, 1)", "VBScript"); //IE Olny,VBScript是只有IE支持的脚本语言
var t=escape(gb2utf8_data).replace(/%u/g,"").replace(/(.{2})(.{2})/g,"%$2%$1").replace(/%([A-Z].)%(.{2})/g,"@$1$2");
t=t.split("@");
var i=0,j=t.length,k;
while(++i<j) {
k=t[i].substring(0,4);
if(!glbEncode[k]) {
gb2utf8_char = eval("0x"+k);
execScript("gb2utf8_char = Chr(gb2utf8_char)", "VBScript"); //IE Olny
glbEncode[k]=escape(gb2utf8_char).substring(1,6);
}
t[i]=glbEncode[k]+t[i].substring(4);
}
gb2utf8_data = gb2utf8_char = null;
return unescape(t.join("%"));
}
//调用示例
xhr.open("get", "ajax.aspx";
xhr.onreadystatechange = function(){
if (xhr.readyState == 4)
if (xhr.status == 200)
var text=(gb2_To_utf8(xhr.responseBody)); //IE6及以下 Olny,要使用responseBody属性
};
xhr.send(null);
2.运用XHR异步刷新页面
异步刷新页面是发生在成功返回后进行。刷新一般是通过操纵DOM模型(Document Object Module文档对象模型)来实现。DOM模型把文档结构化,每一个结点都是一个对象,这个对象有属性和方法,因此可以对结点进行操作,并且立即反应到浏览器页面上。例如:document.creatElement(elementName)方法可以创建一个指定标记名称的新结点对象,当执行parentElementObject.appendChild(childElenmetObject)方法则可以把一个指定的子结点对象的引用添加到父结点的引用,并且父结点的改变会立即反应到页面上。
实际上,刷新时通常用到的是改变结点的内容,使用innerHTML属性。该属性可以改变并立即呈现在结点标记之间的HTML片段内容。
<head>
<script type="text/javascript">
var xhr=creatXMLHttpReauest() //调用创建XHR对象的封装函数,代码略
xhr.open("get","ajax.aspx?arg=a&arg=b");
xhr.onreadystatechange=function() {
if(xhr.readyState==4) {
if(xhr.status==200) {
document.getElementById("div1").innerHTML=xhr.responseText;
}
}
}
xhr.send(null);
</script>
</head>
<body>
<div id="div1"></div>
</body>
</html>
运行的结果是,页面显示了ajax.aspx页面返回结果,并且把HTML代码解释呈现在页面上。如果没有这段JS代码,页面将是空白。如果把上面的代码写成一个函数,并且在页面上运行后用一个事件触发调用,效果很明显,就是在不知觉的情况下,页面内容发生了变化,这就是异步刷新。
index.html 页面代码
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>ajax</title>
<script type="text/javascript">
function creatXMLHttpReauest()
{
try{return new ActiveXObject('Msxml2.XMLHTTP'); /*IE5.0*/}catch(e){}
try{return new ActiveXObject('Microsoft.XMLHTTP'); /*IE5.5*/}catch(e){}
try{return new XMLHttpRequest();/*IE7及其他类型浏览器*/}catch(e){}
return null;
}
function getWebRequest()
{
var xhr=creatXMLHttpReauest() //调用创建XHR对象的封装函数
xhr.open("get","ajax.html");
xhr.onreadystatechange=function()
{
if(xhr.readyState==4) {
if(xhr.status==200) {
document.getElementById("panel1").innerHTML=xhr.responseText;
}
}
}
xhr.send(null);
}
</script>
</head>
<body>
<span id="panel1">1233</span>
<input type="button" onclick="getWebRequest()" value="进行异步请求"/>
</body>
</html>
ajax.html页面代码,注意将这个文件用UTF8编码保存,否则会出现中文乱码。
3.XHR的调用的探讨
- Ajax无刷新方法纵览(1)—XMLHttpRequest对象
- XMLHttpRequest对象无刷新技术
- AJAX—XMLHttpRequest对象
- Ajax技术1——XMLHttpRequest对象
- js+xmlHttpRequest实现无刷新二级级联菜单(ajax原始)
- ajax-不用XMLHttpRequest()实现页面无刷新投票
- ajax无刷新自动更新方法
- 【AJAX】——XMLHttpRequest对象
- Ajax—了解XMLHttpRequest对象
- AJAX—核心XMLHttpRequest对象
- 如何使用XMLHTTPRequest对象实现无刷新效果
- php与Ajax(二)—XMLHttpRequest对象的方法与属性
- ajax XMLHttpRequest 对象 的属性与方法
- Ajax创建XMLHttpRequest对象通用方法
- ajax获取XMLHttpRequest对象的通用方法
- ajax-XMLHttpRequest()对象,属性及方法
- Ajax核心对象——XMLHttpRequest对象
- Ajax核心对象——XMLHttpRequest对象
- 这些所谓的文人专家都该枪毙【原创】
- 共看海天成一色——河北乐亭游记(预热篇)
- 范仲淹
- 读visual studio net使用技巧_chinese学技巧
- 一个学生成绩管理系统的代码
- Ajax无刷新方法纵览(1)—XMLHttpRequest对象
- 今天的感想
- Not Marry Lifelong
- 删除数据中重复的纪录
- C# 2.0与泛型
- java模式之单例模式
- 总想写点什么,但又不知从何下笔
- 合并
- Linux那些事儿之我是Hub(16)盖茨家对Linux代码的影响