前言
一直没痛下决心学习JQuery,但平时项目中又要用到Ajax,于是自己写一个函数封装一下方便项目中偷懒吧!今天一不小心看到介绍xmlHttp对象的博客,细读一下重新认识了一下xmlHttp对象,获益良多,顺便重构一下自己写的Ajax函数。
主要参考:轻松掌握XMLHttpRequest对象
认识XmlHttp对象
XmlHttp:提供客户端与http服务器通信的协议。对于IE浏览器通过window.ActiveXObject()获取,其他浏览器用window.XMLHttpRequest()获取。
XmlHttp对象的属性:
XmlHttp对象的方法:
其中readyState有0,1,2,3,4这五个值
0:实例化了xmlHttp对象,还没调用xmlHttp对象的open方法;
1:调用xmlHttp对象的open方法,但还没调用send方法;
2:调用send方法后,服务器返回响应头,这时可以通过xmlHttp.getResponseHeader()来获取响应头;
3:服务器返回部分响应内容,这时可以xmlHttp.responseText有值,但只是部分内容而已,不能保证数据完整;
4:服务器处理完毕,这时xmlHttp.responseText的值为完整的响应内容,数据完整。
注意:
1.上面的readyState不是每种浏览器都俱全。
2. 因asp.net默认启动了输出缓存,如果不手动加上Response.Flush()的话,那么最后响应完成后2、3、4状态会一连串地变换。
具体实现
代码:
XmlHttpManagerHasPool.js
function XmlHttpManagerHasPool()
{
/*私有方法Start*/
var CreateXmlHttp = function(){
if(window.XMLHttpRequest)
{
return new XMLHttpRequest(); //非ie浏览器
}
else if(window.ActiveXObject)
{
return new ActiveXObject("Microsoft.XMLHTTP"); //ie浏览器
}
else
{
return null;
}
}
var xmlHttpPool = null;
var initXmlHttpCount = 3;//默认对象池中xmlHttp对象个数
var Init_Pool = function(){
xmlHttpPool = new Array();
var tempXmlHttp = null;
for(var i=initXmlHttpCount-1; i>=0; --i)
{
tempXmlHttp = CreateXmlHttp();
if(tempXmlHttp)
xmlHttpPool.push(tempXmlHttp);
}
}
/*私有方法End*/
/*公开方法和事件Start*/
//下面是一系列事件
var OnNoXmlHttp = null;//当无法获取xmlHttp对象时触发,仅接受方法
this.SetOnNoXmlHttp = function(method){
if(typeof method=="function")
OnNoXmlHttp = method;
}
var OnOpen = null;//当xmlHttp对象调用open方法后触发,仅接受方法。readyState由0变为1
this.SetOnOpen = function(method){
if(typeof method=="function")
OnOpen = method;
}
var OnPreLoad = null;//当xmlHttp对象调用send方法,服务器发送响应头信息后触发,仅接受方法。readyState由1变为2
this.SetOnPreLoad = function(method){
if(typeof method=="function")
OnPreLoad = method;
}
var OnLoading = null;//服务器发送部分响应内容后触发,readyState由2变为3,仅接受方法
this.SetOnLoading = function(method){
if(typeof method=="function")
OnLoading = method;
}
//当status不为200时触发,有默认处理函数,仅接受方法
var OnError = function(xmlHttp){
alert("Request is fail. Http Status Code:"+xmlHttp.status);
}
this.SetOnError = function(method){
if(typeof method=="function")
OnError = method;
}
//初始化xmlHttp对象池
this.InitPool = function(){
Init_Pool();
}
//参数:postPar——当请求方式为POST时,所要传递的参数
// url——异步处理程序url
// method——请求方式:GET/POST
// onLoadComplete——请求成功后的结果处理程序,该处理程序需要两个参数:第一个参数为XMLHttpRequest对象,第二个参数为触发事件的对象(可选)
// argData——附件参数(可选),若要传多个值,可以用数组或map对象
this.Startup = function(postPar,url,method,onLoadComplete,argData){
//获取xmlHttp对象
if(xmlHttpPool==null)
{
Init_Pool();
}
var xmlHttp = null;
if(xmlHttpPool.length>=1)
{
xmlHttp = xmlHttpPool.shift();
}
else
{
xmlHttp = CreateXmlHttp();
}
if(xmlHttp==null)
{
if(OnNoXmlHttp)
OnNoXmlHttp();
return false;
}
//成功获取
var argumentLength = arguments.length;
xmlHttp.onreadystatechange = function(){
switch(xmlHttp.readyState)
{
case 1:
if(OnOpen)
OnOpen();
break;
case 2:
if(OnPreLoad)
OnPreLoad();
break;
case 3:
if(OnLoading)
OnLoading();
break;
case 4:
if(xmlHttp.status == 200 && xmlHttp.statusText == "OK" )
{
switch(argumentLength)
{
case 5:
if(onLoadComplete!=null)
{
onLoadComplete(xmlHttp,argData);
}
break;
case 4:
if(onLoadComplete!=null)
{
onLoadComplete(xmlHttp);
}
break;
default:
alert("The number of argument is wrong!");
return;
}
}
else if(OnError){
OnError(xmlHttp);
}
xmlHttp.abort();//将xmlHttp的readyState设为0
xmlHttpPool.push(xmlHttp);//释放回对象池
break;
default:
if(OnError)
{
OnError(xmlHttp);
xmlHttp.abort();//将xmlHttp的readyState设为0
xmlHttpPool.push(xmlHttp);//释放回对象池
}
break;
}
}
xmlHttp.open(method,url,true);
if(method.toLowerCase() == "get")
{
xmlHttp.send(null);
}
else
{
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", postPar.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.send(postPar);
}
}
/*公开方法和事件End*/
}
使用实例——进度条:
aspx文件
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FlushTest.aspx.cs" Inherits="Client.FlushTest" %>
<input type="button" id="btn" value="Click" onclick="Click()" />
<br />
<div style="height:20px;width:100px;overflow:hidden;border:solid 1px black">
<div id="divProcess" style="height:20px;width:0px;background-color:Green"></div>
</div>
<div id="divText" style="width:100px">0%</div>
<script src="XmlHttpManagerHasPool.js" type="text/javascript"></script>
<script type="text/javascript">
var dp = document.getElementById("divProcess");
var dt = document.getElementById("divText");
var xhp = new XmlHttpManagerHasPool();
xhp.SetOnNoXmlHttp(function(){alert("noxmlhttp");});
function onopen(){
dp.style.width = "25px";
dt.innerHTML = "25%";
}
xhp.SetOnOpen(onopen);
function onpreload(){
dp.style.width = "50px";
dt.innerHTML = "50%";
}
xhp.SetOnPreLoad(onpreload);
function onloading(){
dp.style.width = "75px";
dt.innerHTML = "75%";
}
xhp.SetOnLoading(onloading);
function onloadc(){
dp.style.width = "100px";
dt.innerHTML = "100%";
}
function Click(){
xhp.Startup(null,"Handler1.ashx","get",onloadc);
}
</script>
aspx.cs文件
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
Thread.Sleep(5000);
context.Response.Flush();//发送响应头,readyState由1变为2
Thread.Sleep(5000);
context.Response.Write("Hello World");
context.Response.Flush();//发送部分响应内容,readyState由2变3
Thread.Sleep(5000);
context.Response.Write("Hello World");
//响应内容发送完毕,readyState由3变4
}
public bool IsReusable
{
get
{
return false;
}
}
}
Ajax封装包基本写好了,不过对于JavaScript依然有很多不清楚的地方,要好好学一下才行。