其默認實現封裝了XMLHttpRequest的功能
<script language="Javascript" type="text/Javascript">
function getXMLHttpRequest()
...{
if (window.XMLHttpRequest)
...{
//適用於Firefox浏覽器創建異步通訊對象
return new window.XMLHttpRequest();
}
else
...{
//適用於IE來創建異步通訊對象,兩個是不同的版本
var progIDs = [ ''Msxml2.XMLHTTP'', ''Microsoft.XMLHTTP'' ];
for (var i = 0; i < progIDs.length; i++)
...{
&nb
...{
var XMLHttp = new ActiveXObject(progIDs[i]);
return XMLHttp;
}
catch (ex) ...{ }
}
return null;
}
}
function sendRequest()
...{
var xhr = getXMLHttpRequest();
xhr.open("POST", "Handlers/RandomNumber.ashx");
//設置准備狀態改變的回調函數
xhr.onreadystatechange = function()
...{
//設置onReadyStateChange作為回調函數
//將異步通訊對象作為this的上下文
onReadyStateChange.apply(xhr);
}
xhr.send(null);
}
function onReadyStateChange()
...{
//異步通訊對象的readyState的5種狀態
//0 - (未初始化)還沒有調用send()方法
//1 - (載入)已調用send()方法,正在發送請求
//2 - (載入完成)send()方法執行完成,已經接收到全部響應內容
//3 - (交互)正在解析響應內容
//4 - (完成)響應內容解析完成,可以在客戶端調用了
if (this.readyState == 4)
.. //Http響應狀態,值很多,但是我們只需要知道200為正常返回
if (this.status == 200)
...{
alert(this.responseText);
}
else
...{
throw new Error();
}
}
}
</script> 上例是不實用ASP.Net AJax客戶端架構,直接進行異步通訊的示例,在服務端是使用Response.Write來返回客戶端數據
2、使用ASP.Net AJax異步通訊層
ASP.Net AJax異步通訊層主要有三個類WebRequest、WebRequestExecutor、WebRequestManager,這三個類都在Sys.Net命名空間下。
- WebRequest類:負責收集(存儲)請求信息。 事件completed 得到回復後觸發,就是表明這個異步傳輸已經由服務器那邊給出了回應,不管這個回應是錯誤的還是超時的 add_completed/remove_completed 添加/移除completed事件的事件處理器 getResolvedUrl 獲得完整的URL invoke 執行(發送)請求 set_url(url) 設置服務器響應頁面/Handler的地址 get_headers() 得到請求的頭信息集合 set_body(data) 設置發送到服務器的請求內容 set_httpVerb(verb) 設置請求所用的Http方法(Post, Get, Put,) set_timeout(time) 設置超時時間
get_executor()
得到發送請求的Executor對象 set_userContext 設置附加於WebRequest的對象
<script language="Javascript" type="text/Javascript">
var webRequest = null;
function sendRequest(action)
...{
var ff = [1, 2, 3, 4];
webRequest = new Sys.Net.WebRequest();
webRequest.set_url("Handlers/Complex.ashx");
webRequest.get_headers()["action"] = action;
webRequest.set_body("data=" + encodeURIComponent("Hello World!"));
webRequest.set_httpVerb("POST");
webRequest.set_timeout(3000);
webRequest.set_userContext(ff);
webRequest.add_completed(onCompleted);
webRequest.invoke();
}
function onCompleted(response, eventArgs)
...{
//得到請求Request裡面的設備上下文
alert(response.get_webRequest().get_userContext());
if (response.get_aborted())
...{
alert("Request aborted!");
}
else if (response.get_responseAvailable())
...{
var statusCode = response.get_statusCode();
if ((statusCode < 200) || (statusCode >= 300))
...{
alert("Error occurred!");
}
else
...{
alert(response.get_responseData());
// response.get_XML();
// response.get_object();
// response.getResponseHeader(...);
}
}
else if (response.get_timedOut())
...{
alert("Request timed out!");
}
else
...{
alert("Error occurred!");
}
}
</script>如上例是一個使用Microsoft ASP.Net AJax架構來進行異步傳輸的例子,上例中有一個set_userContext(Object),這個方法是設置webRequest的用戶上下文,設置以後,userContext的內容不會傳輸到服務端(據我觀察),他將會把這個屬性傳到completed事件處理器中。在上例中使用到了WebRequestExecutor類,response就是WebRequestExecutor類,這個類的屬性與方法如下 abort() 取消當前請求 executeRequest() 執行請求 getAllResponseHeaders() 獲取回復內所有的頭信息,返回值是一個集合 getResponseHeader(HeaderName) 獲取回復內指定的頭信息 get_aborted()/set 表示請求是否被取消 get_responseAvailable() 表示是否得到了正確的結果 get_responseData() 獲得字符串形勢的回復內容 get_started() 表示請求是否已經開始 get_statusCode() 表示回復狀態的代碼 get_statusText() 表示回復狀態的文字 get_timedOut() 表示回復是否是超時狀態 get_xml() 獲得XML形式的回復內容 get_webRequest() 獲得當前正在執行的WebRequest對象
在上面兩個類的方法和屬性說明中,get_/set_開頭的是屬性,屬性應該有響應的get/set方法,我只標明了一部分,但是有的屬性肯定是只讀屬性,這裡我沒有明確標明,也沒有嘗試,在實際編程中,應該很容易知道哪個是只讀屬性。在發送請求的函數中可以使用webRequest.get_executor()來得到WebRequestExecutor類的實例,在completed事件處理函數中,可以通過webRequestExecutor.get_webRequest得到webRequest類的實例,有點循環引用的意思。
3、WebRequestManager類的說明 invokingRequest事件 即將發出請求時觸發,可用於取消某個請求 completedRequest事件 請求結束時觸發,它早於WebRequest對象的completed事件觸發 defaultTimeout屬性 默認的超時時間 defaultExecutorType 默認的發送請求的Executor類型 add/remove_invokingRequest(handler) 添加/移除invokingRequest的事件處理器 add/remove_completedRequest(handler) 添加/移除completedRequest的事件處理器
<ASP:ScriptManager ID="ScriptManager1" runat="server" />
<ASP:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<%= DateTime.Now %><br />
<ASP:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</ASP:UpdatePanel>
<script language="Javascript" type="text/Javascript">
Sys.Net.WebRequestManager.add_invokingRequest(function(sender, eventArgs)
...{
debugger
if (confirm("Cancel the partial rendering?"))
...{
eventArgs.set_cancel(true);
}
});
Sys.Net.WebRequestManager.add_completedRequest(function()
...{
alert("Response received!");
});
</script>記得UpdatePanel中有一個PageRequestManager類,這個類適用與頁面級別的調用,WebRequestManager是對web請求適用,並且PageRequestManager的initializeRequest事件優先與invokingRequest事件,從名字上就可以區分出來一個是初始化事件,一個是調用請求的事件。上面這個例子有一個bug,取消請求之後要重新刷新頁面才能正常的調用。這個bug我還沒有找到好的方法解決。注意:在這個例子中WebRequestManager類是結合UpdatePanel使用的,能否在與WebRequest和WebRequestExecutor類結合使用,還不是很清楚