下面关注XmlHttpExecutor的executeRequest()方法 
function SysNetXMLHttpExecutorexecuteRequest() 
{
 //检测参数个数,如果不等于0,那么抛出异常
 if (arguments.length !== 0) throw Error.parameterCount();
 //得到WebRequest对象,用来将保存的信息传递出去
 //在WebRequest对象的set_executor方法里,已经将执行者对应的
 //WebRequest对象设置到执行者中,并且set_executor方法是基类
 //WebRequestExecutor类的方法,这里调用的是基类的方法
 this._webRequest = this.get_webRequest();
 //判断这个执行者是否已经开始传递数据,如果已经开始传递,那么抛出异常
 if (this._started) 
 {
 throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, 'executeRequest'));
 }
 //判断webRequest对象是否为空,为空就抛出异常
 if (this._webRequest === null) 
 {
 throw Error.invalidOperation(Sys.Res.nullWebRequest);
 }
 //得到WebReuqest对象的body
 var body = this._webRequest.get_body();
 //得到WebReuqest对象的header集合
 var headers = this._webRequest.get_headers();
 //这一段代码是标准的ajax应用
 //实例化一个xmlHttpRequest对象
 this._xmlHttpRequest = new XMLHttpRequest();
 //给定状态改变的回调函数
 this._xmlHttpRequest.onreadystatechange = this._onReadyStateChange;
 //得到WebReuqest对象的请求动作
 var verb = this._webRequest.get_httpVerb();
 //指定请求的连接和动作,并表明是一个异步传输
 this._xmlHttpRequest.open(verb, this._webRequest.getResolvedUrl(), true );
 if (headers) 
 {
 //遍历header集合
 for (var header in headers) 
 {
 var val = headers[header];
 //如果header不是js函数
 if (typeof(val) !== "function")
 //将header设置到xmlHttpRequest对象的请求头里
 this._xmlHttpRequest.setRequestHeader(header, val);
 }
 }
 //判断动作是否是post
 if (verb.toLowerCase() === "post") 
 {
 //通过设定的头,来设置传送内容的类型
 if ((headers === null) || !headers['Content-Type']) 
 {
 this._xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 }
 if (!body) 
 {
 body = "";
 }
 }
 //得到WebReuqest对象的超时时间
 var timeout = this._webRequest.get_timeout();
 //如果设置了超时时间
 if (timeout > 0) 
 {
 //创建一个onTimeout函数的委托,并把XmlHttpExecutor对象作为this的上下文,
 //并指定在超时时间后执行这个委托,将返回的对象放在_time内部成员里方便clearTimeout
 this._timer = window.setTimeout(Function.createDelegate(this, this._onTimeout), timeout);
 }
 this._xmlHttpRequest.send(body);
 //设置执行这已经开始标识
 this._started = true;
} 
 
在上面这个方法里,我们要关注3个方法 
第一个是_onReadyStateChange方法,这个方法将在ReadyState改变是被调用 
this._onReadyStateChange = function () 
{
 //如果readState状态为4,表明成功返回
 if (_this._xmlHttpRequest.readyState === 4 ) 
 {
 //清除超时时间
 _this._clearTimer();
 //设置响应状态为可用
 _this._responseAvailable = true;
 //告诉webRequest对象,我已经完成请求了
 _this._webRequest.completed(Sys.EventArgs.Empty);
 //如果ajax异步传输对象不为空
 if (_this._xmlHttpRequest != null) 
 {
 //清除xmlHttpRequest的onreadystatechange委托
 _this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
 //清除ajax异步传输对象
 _this._xmlHttpRequest = null;
 }
 }
} 
 
第二个方法是_onTimeout,超时后执行的方法 
this._onTimeout = function this_onTimeout() 
{
 if (!_this._responseAvailable) 
 {
 //清除超时时间设置的委托
 _this._clearTimer();
 //设置超时标志为true
 _this._timedOut = true;
 //清除xmlHttpRequest异步操作对象的onreadystatechange的回调函数
 _this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
 //取消xmlHttpRequest对象异步传输
 _this._xmlHttpRequest.abort();
 //告诉webRequest对象我已经完成操作
 _this._webRequest.completed(Sys.EventArgs.Empty);
 _this._xmlHttpRequest = null;
 }
} 
 
第三个是XMLHttpRequest的构造函数 
if (!window.XMLHttpRequest) 
{
 window.XMLHttpRequest = function windowXMLHttpRequest() 
 {
 var progIDs = [ 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP' ];
 for (var i = 0; i < progIDs.length; i++) 
 {
 try
 {
 var xmlHttp = new ActiveXObject(progIDs[i]);
 return xmlHttp;
 }
 catch (ex) 
 {
 }
 }
 return null;
 }
} 
 
这是为了适应各种类型的浏览器,与我们原来创建标准的ajax异步传输例子相同
我们还要关注WebRequest.completed方法 
function SysNetWebRequestcompleted(eventArgs) 
{
 //检测参数
 var e = Function._validateParams(arguments, [{name: "eventArgs", type: Sys.EventArgs}]);
 if (e) throw e;
 //得到WebRequestManger的completedRequest事件委托
 var handler = Sys.Net.WebRequestManager._get_eventHandlerList().getHandler("completedRequest");
 //如果存在这样的委托,那么调用这个委托,参数为执行者和args参数
 if (handler) 
 {
 handler(this._executor, eventArgs);
 }
 //继续得WebRequest的completed事件委托,那么我们可以看到WebRequestManager的completedRequest事件是
 //优先于WebRequest的completed事件的
 handler = this._get_eventHandlerList().getHandler("completed");
 //执行委托
 if (handler) 
 {
 handler(this._executor, eventArgs);
 }
} 
 
XmlHttpExecutor.abort()方法 
function SysNetXMLHttpExecutorabort() 
{
 //判断参数
 if (arguments.length !== 0) throw Error.parameterCount();
 //如果执行者没有执行,抛出异常
 if (!this._started) 
 {
 throw Error.invalidOperation(Sys.Res.cannotAbortBeforeStart);
 }
 //如果执行者的状态已经是abort,或者相应是无效的或者超时,那么直接返回
 if (this._aborted || this._responseAvailable || this._timedOut)
 return;
 //设置abort标志
 this._aborted = true;
 //清除超时设置
 this._clearTimer();
 //如果异步传输对象存在,并且还没有返回任何信息
 if (this._xmlHttpRequest && !this._responseAvailable) 
 {
 this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
 this._xmlHttpRequest.abort();
 this._xmlHttpRequest = null;
 //得到WebRequest对象的Completed事件委托
 var handler = this._webRequest._get_eventHandlerList().getHandler("completed");
 if (handler) 
 {
 handler(this, Sys.EventArgs.Empty);
 }
 }
} 
 
我们可以看到除了超时,成功响应,错误,中断都会触发WebRequest的compeleted事件。
下面的一个例子是模仿XmlHttpExecutor类,并且支持跨域名访问
首先是ScriptReferenceExecutor类
Sys.Net.ScriptReferenceExecutor = function()
{
 //初始化基类
 Sys.Net.ScriptReferenceExecutor.initializeBase(this);
 //设定各个字段的初始值
 this._responseAvailable = false;
 this._timedOut = false;
 this._aborted = false;
 this._started = false;
 this._responseData = null;
 this._statusCode = 0;
 this._statusText = null;
 
 this._uniqueKey = null;
 this._timer = null;
 this._scriptElement = null;
}
Sys.Net.ScriptReferenceExecutor.prototype = 
{
 get_responseAvailable : function()
 {
 return this._responseAvailable;
 },
 
 get_timedOut : function()
 {
 return this._timedOut;
 },
 
 get_aborted : function()
 {
 return this._aborted;
 },
 
 get_started : function()
 {
 return this._started;
 },
 
 get_responseData : function()
 {
 return this._responseData;
 },
 
 get_statusCode : function()
 {
 return this._statusCode;
 },
 
 get_statusText : function()
 {
 return this._statusText;
 },
 
 get_xml : function()
 {
 return new XMLDOM(this.get_responseData());
 },
 
 //执行请求的方法
 executeRequest : function()
 {
 //设置开始标记为true
 this._started = true;
 
 //得到WebRequest对象,就得到了保存在WebRequest中的各种值
 var request = this.get_webRequest();
 //得到序列化对象
 var serializer = Sys.Serialization.JavaScriptSerializer;
 
 //得到WebRequest对象请求的url地址
 var scriptUrl = request.get_url() + "?";
 //组合头集合,并将头集合序列化,并且用Url转换字符
 scriptUrl += (("headers=") + encodeURIComponent(serializer.serialize(request.get_headers())));
 //组合body
 scriptUrl += ("&body=" + encodeURIComponent(serializer.serialize(request.get_body())));
 
 //得到一个执行者对象的唯一标识符,方便找到对应的执行者
 var uniqueKey = this._uniqueKey = this._generateUniqueKey();
 scriptUrl += ("&uniqueKey=" + encodeURIComponent(serializer.serialize(uniqueKey)));
 //设置对应的执行者到执行者集合里
 Sys.Net.ScriptReferenceExecutor._executors[uniqueKey] = this;
 
 //创建脚本元素
 var scriptElement = this._scriptElement = document.createElement("script");
 scriptElement.type = "text/javascript";
 scriptElement.language = "javascript";
 //将脚本元素的src设置为组合好的url
 scriptElement.src = scriptUrl;
 //得到页面的head元素,因为head没有ID,只能通过TagName得到,然后将
 //脚本元素追加到头
 document.getElementsByTagName("head")[0].appendChild(scriptElement);
 
 //得到超时事件
 var timeout = request.get_timeout();
 if (timeout > 0)
 {
 //设置超时后执行的委托
 this._timer = window.setTimeout(
 Function.createDelegate(this, this._onTimeout), timeout);
 }
 
 },
 
 _onTimeout : function()
 {
 this.complete(null, null, null, false, true, false);
 },
 
 abort : function()
 {
 this.complete(null, null, null, false, false, true);
 },
 
 _generateUniqueKey : function()
 {
 return Math.random().toString();
 },
 
 //执行者的完成函数参数为状态代码、状态描述、body、是否返回成功、是否超时、是否中断操作
 complete : function(statusCode, statusText, body, responseAvailable, timedOut, aborted)
 {
 this._statusCode = statusCode;
 this._statusText = statusText;
 this._responseData = body;
 this._responseAvailable = responseAvailable;
 this._timedOut = timedOut;
 this._aborted = aborted;
 
 //清除超时事件
 if (this._timer)
 {
 window.clearTimeout(this._timer);
 }
 //移除已经提交给服务气的脚本元素,也就是url
 document.getElementsByTagName("head")[0].removeChild(this._scriptElement);
 //删除已经执行的执行者
 delete Sys.Net.ScriptReferenceExecutor._executors[this._uniqueKey];
 
 //调用WebRequest的completed方法
 this.get_webRequest().completed(Sys.EventArgs.Empty);
 }
}
//注册类
Sys.Net.ScriptReferenceExecutor.registerClass("Sys.Net.ScriptReferenceExecutor", Sys.Net.WebRequestExecutor);
Sys.Net.ScriptReferenceExecutor._executors = new Object();
//执行者的静态complete方法
Sys.Net.ScriptReferenceExecutor.complete = function(uniqueKey, statusCode, statusText, body)
{
 //判断执行者是否存在
 var executor = Sys.Net.ScriptReferenceExecutor._executors[uniqueKey];
 if (executor)
 {
 //调用执行者对象的complete方法。
 executor.complete(statusCode, statusText, body, true, false, false);
 }
}
 
再是接受请求的服务端
<%@ WebHandler Language="C#" Class="ScriptReferenceExecutor" %>
using System;
using System.Web;
using System.Collections.Generic;
using System.Web.Script.Serialization;
public class ScriptReferenceExecutor : IHttpHandler {
 
 public void ProcessRequest (HttpContext context) 
 {
 context.Response.ContentType = "text/plain";
 // context.Response.Write("alert('Message Received!');");
 //得到序列化对象
 JavaScriptSerializer serializer = new JavaScriptSerializer();
 //反序列化头集合为字典集合
 Dictionary headers = serializer.Deserialize>(
 context.Request.QueryString["headers"]);
 //反序列化body为字符串
 string body = serializer.Deserialize(context.Request.QueryString["body"]);
 //反序列化执行者对象的标识
 string uniqueKey = serializer.Deserialize(context.Request.QueryString["uniqueKey"]);
 string action = headers["action"];
 if (action == "normal")
 {
 this.SendResponse(context, uniqueKey, 200, "OK", "You've send: " + body);
 }
 else if (action == "error")
 {
 this.SendResponse(context, uniqueKey, 500, "Error", null);
 }
 else
 {
 System.Threading.Thread.Sleep(5000);
 }
 }
 //发送响应信息
 private void SendResponse(HttpContext context, string uniqueKey, int statusCode, string statusText, string body)
 {
 //调用ScriptReferenceExecutor的静态方法complete
 context.Response.Write("Sys.Net.ScriptReferenceExecutor.complete('" + uniqueKey + "', ");
 context.Response.Write("'" + statusCode + "', ");
 context.Response.Write("'" + statusText + "', ");
 context.Response.Write(new JavaScriptSerializer().Serialize(body) + ");");
 }
 
 public bool IsReusable 
 {
 get 
 {
 return false;
 }
 }
}
剩下的就是页面使用
<%@ Page Language="C#" %>
 Use Async Communication Layer
 
 
 
这就是继承并扩展WebRequestExecutor类