运用Ajax的方法有两种:
一、用hidden frame作为数据的发送、接收器
二、用XmlHttp Request对象进行数据的发送、接收
frameset 方式
get方法
创建两个frame,分别用来显示信息和接收信息
<frameset rows="100%,0" frameborder="0">
<frame name=" displayFrame" src=" display.htm" noresize=" noresize" />
<frame name=" hiddenFrame" src=" about:blank" noresize=" noresize" />
</frameset>
rows="100%, 0" frameborder="0" 是为了隐藏第二个frame,即hiddenFrame
在display.htm中的HTML代码:
<input type="text" id="txtCuromerId" value="" />
<input type="button" value=" Get Customer Info" onclick=" requestCustomerInfo()" />
requestCustomerInfo()的代码如下
function requestCustomerInfo() {
var sId = document.getElementById("txtCustomerId").value;
top.frames["hiddenFrame"].location = "getcustomerdata.php?id=" + sId;
}
它的作用是获取displayFrame用户输入的数据并将其加入到查询字符串中创建完整的url,然后将这个url指定到hiddenFrame上.这里通过将数据提交给getcustomerdata.php获取结果页面.在结果页面中将包含一个id为divInfoToReturn的div标记,其中包含了返回的信息.
下面的代码在hiddenFrame加载完成后将获取到的信息从hiddenFrame中取出并在displayFrame中显示
window.onload = function () {
var divInfoToReturn = document.getElementById("divInfoToReturn");
top.frames["displayFrame"].displayCustomerInfo(divInfoToReturn.innerHTML);
};
post方法
同样创建两个frame,display.htm的代码如下
<form method="post" action="SaveCustomer.php" target="hiddenFrame">
<p>Enter customer information to be saved:</p>
<p>Customer Name: <input type="text" name="txtName" value="" /><br />
Address: <input type="text" name="txtAddress" value="" /><br />
City: <input type="text" name="txtCity" value="" /><br />
State: <input type="text" name="txtState" value="" /><br />
Zip Code: <input type="text" name="txtZipCode" value="" /><br />
Phone: <input type="text" name="txtPhone" value="" /><br />
E-mail: <input type="text" name="txtEmail" value="" /></p>
<p><input type="submit" value="Save Customer Info" /></p>
</form>
<div id="divStatus"></div>
function saveResult(sMessage) {
var divStatus = document.getElementById("divStatus");
divStatus.innerHTML = "Request completed: "+ sMessage;
}
注意form标记的target属性设置为hiddenFrame,其返回的数据将由hiddenFrame接收.
saveResult()方法在得到页面数据后将数据写入到displayForm的divStatus中
SaveCustomer.php所返回的页面中包含如下代码,用来显示取得的数据
<script type=" text/javascript">
window.onload = function () {
top.frames["displayFrame"].saveResult("<?php echo $sStatus ?>");
}
</script>
XmlHttp Request方式
由于在IE和FireFox上的XmlHttp实现是不同的,这里我使用zXmlHttp,它是XmlHttp的一个跨浏览器包装,对不同浏览器实现了同一个XmlHttp接口.可以在http://www.nczonline.net/downloads/找到它的下载
使用XMLHttp
首先我们用如下代码创建一个XMLHttp对象
var oXmlHttp = zXmlHttp.createRequest();
之后就可以掉用oXmlHttp.open()方法开启HTTP请求了,open()方法有三个参数
Request Type:标识请求方式的字符串,Get或者Post
URL:请求的页面地址
Async:是否异步获取,布尔型.
当Asyn设置为true时,HTTP请求将以异步方式发送,即脚本不等待HTTP的响应.所以必须注册一个事件处理方法来处理返回数据
oXmlHttp.open("get", "info.txt", true);
下来需要定义一个onreadystatechange事件的处理方法,XMLHttp对象有一个名为readyState的属性用来标识请求状态,它有五种取值:
0(未初始化)
1(加载中)
2(已发送请求)
3(部分加载)
4(加载完成)
每当readySate的值发生变化,就会调用onreadystatechange所指定的方法.由于浏览器实现的不同,可靠的readyState属性值只有0,1和4(我在IE6上只能检测到4 =.=).
下面的代码注册一个onreadystatechange处理方法
oXmlHttp.onreadystatechange = function() {
if (oXmlHttp.readyState == 4) {
alert(oXmlHttp.responseText);
}
};
XMLHttp的responseText属性保存了获取的响应数据
最后调用oXmlHttp.send()方法发送HTTP请求,oXmlHttp.send()方法的参数为HTTP请求的body字符串,如果不需要body,则要设置为null(get方法没有body)
完整代码如下:
var oXmlHttp = zXmlHttp.createRequest();
oXmlHttp.open("get", "info.txt", true);
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
alert(oXmlHttp.responseText);
}
};
oXmlHttp.send(null);
运行后将alert所获得的info.txt文件的内容,如果info.txt不存在,则responseText将包含服务器的404消息.这里我们可以通过XMLHttp的status属性读取HTTP状态,statusText包含了当前状态的描述文本(有些浏览器上不会返回任何信息).使用这两个属性就可以确定是否得到数据并且在获取失败时告知用户出了什么问题.
if (oXmlHttp.status == 200) {
alert("Data returned is: "+ oXmlHttp.responseText;
} else {
alert("An error occurred: "+ oXmlHttp.statusText;
}
通常只要当前响应的status值为200就可以确定成功的获得了数据.但算发生错误时readyState也会被设置为4,所以只检测readyState是不够的,通常使用下面的代码检测错误
var oXmlHttp = zXmlHttp.createRequest();
oXmlHttp.open("get", "info.txt", true);
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
if (oXmlHttp.status == 200) {
alert("Data returned is: "+ oXmlHttp.responseText;
} else {
alert("An error occurred: "+ oXmlHttp.statusText;
}
}
};
oXmlHttp.send(null);
XMLHttp的getResponseHeader()方法可以获得HTTP的响应头
var sContentType = oXmlHttp.getResponseHeader("Content-Type");
if (sContentType == "text/xml") {
alert("XML content received.");
} else if (sContentType == "text/plain") {
alert("Plain text content received.");
} else {
alert("Unexpected content received.");
}
Content-Type标识所获取数据的类型
如果想要获取所有HTTP响应头,可以调用getAllResponseHeaders()方法
var sHeaders = oXmlHttp.getAllResponseHeaders();
var aHeaders = sHeaders.split(/\r?\n/);
for (var i=0; i < aHeaders.length; i++) {
alert(aHeaders[i]);
}
对于HTTP请求的头可以通过setRequestHeader()方法设置,可以指定我们要发送内容的类型
var oXmlHttp = zXmlHttp.createRequest();
oXmlHttp.open("get", "info.txt", true);
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
alert("Got response.");
}
};
oXmlHttp.setRequestHeader("myheader", "myvalue"); // before send request
oXmlHttp.send(null);
XMLHttp Post方式
在页面的form标记中我们需要捕捉onsubmit事件好把提交数据的工作交给XMLHttp来做
<form method="post" action="SaveCustomer.php"
onsubmit="sendRequest(); return false">
.....</form>
post方式发送的数据格式如下
name1=value1&name2=value2&name3=value3
每个name和value都必须是URL-Encoded,JavaScript的encodeURIComponent可以完成这个工作
function getRequestBody(oForm) {
var aParams = new Array();
for (var i=0 ; i < oForm.elements.length; i++) {
var sParam = encodeURIComponent(oForm.elements[i].name);
sParam += "=";
sParam += encodeURIComponent(oForm.elements[i].value);
aParams.push(sParam);
}
return aParams.join("&");
}
function sendRequest() {
var oForm = document.forms[0];
var sBody = getRequestBody(oForm);
var oXmlHttp = zXmlHttp.createRequest();
oXmlHttp.open("post", oForm.action, true);
oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4) {
if (oXmlHttp.status == 200) {
saveResult(oXmlHttp.responseText);
} else {
saveResult("An error occurred: "+ oXmlHttp.statusText);
}
}
};
oXmlHttp.send(sBody);
}
注意最后调用send()方法时传入了被格式化的数据,还有在发送之前设置了Content-Type头为application/x-www-form-urlencoded,大部分服务器端脚本是用这个头来判断是否是Post的数据.
优缺点
hidden frameset方式操作相对XMLHttp繁琐,但用可以可是使用浏览器的前进后退功能,XMLHttp不会产生历史记录,所以就不能用浏览器的前进后退.
对于IE浏览器,如果用户禁用了ActiveX,XMLHttp将不可用,但hidden frameset可以工作.