在web应用中,前台和后台通信交互是必不可少的,如:js获取后台数据库信息、用户在前端发送控制指令等等,这些都需要通信交互。
一般的方式是:后台暴露一个接口,然后前端对该接口发送请求,并附带相关参数。后台暴露的接口统称为web service,其中按协议分为:SOAP 和REST的。从统一性和标准性来说,基于REST的服务接口无疑是当今的主流。
前端获取后台信息的方式也有很多种,如:asp/jsp前后台代码混合的方式;使用<script>、<iframe>标签请求后台信息;以及现在大规模的ajax方式。ajax方式对于一般web应用开发者来说,可以借助于第三方ajax框架来完成,主流的ajax框架有:JQuery、Dojo、Ext等等,他们不但有丰富的UI效果,封装了浏览器之间的差异,而且在使用ajax上也是十分简洁。
在有些情况,我们希望了解ajax框架这些异步请求的内部是如何做到的,而XmlHttpRequest正是ajax的核心。
以下说明都是基于XmlHttpRequest的ajax方式。
第一段代码演示的功能有:
1、XmlHttpRequest中如何同步和异步ajax请求?
2、如何请求Soap协议的服务?
3、如何传递不同的数据结构给服务的(分:xml/json)?
4、asp.net封装的ScriptManager是怎么实现ajax的?
Ajax方式 XmlHttpRequest/ScriptManger
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="commAjax.aspx.cs" Inherits="commAjax" %>
2
3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4 <html xmlns="http://www.w3.org/1999/xhtml">
5 <head id="Head1" runat="server">
6 <title></title>
7 <script type="text/javascript">
8 function commAjaxClick() {
9 var XHR = getXMLHttpRequest();
10 var _format = "json";
//
"xml";//
11
//
回调函数是否同步。如这个XHR为同步的话,的等XHR回调方法执行完毕后,再执行DClientService的相关方法。调试可看效果。
12
var _isAsynchro =
false;
//
true; //
13
//
注意URL格式,DClientDemo为需要调用的方法。_isAsynchro为是否异步。如果为true的话同时进行。
14
XHR.open("POST", "http://localhost/DClientService/DClientService.asmx/DClientDemo", _isAsynchro);
//
http post 需要加 /DClientDemo
15
if (_format == "xml") {
16 XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); //
http post : application/x-www-form-urlencoded;SOAP 1.1:text/xml; charset=utf-8
17
//
XHR.setRequestHeader("SOAPAction", "http://tempuri.org/DClientDemo"); //SOAP 1.1需要设置
18
XHR.onreadystatechange =
function () { httpReqCallback.apply(XHR); };
//
XHR应用于回调函数中的this
19
XHR.send("req='wangsh'&_age=26&_salary=8600.5&_isWedding=true");
20 //
post方式的参数格式:"req='wangsh'&_age=26&_salary=8600.5&_isWedding=true"
21
//
get方式:send方法没有无法传递参数,可以在url携带参数,格式如:url+"?req='wangsh'&_age=26"
22
}
23 else
if (_format == "json") {
24 //
Content-Type设置为json格式,即数据以json进行交换,得到的结果也是json的
25
XHR.setRequestHeader("Content-Type", "application/json; charset=utf-8");
26 XHR.onreadystatechange = function () { httpReqCallback.apply(XHR); };
//
XHR应用于回调函数中的this
27
var parObj =
new Object();
28 parObj.req = 'wangsh';
29 parObj._age = 26;
30 parObj._salary = 8600.5;
31 parObj._isWedding = true;
32 XHR.send(Sys.Serialization.JavaScriptSerializer.serialize(parObj));
33 }
34
35 //
以下为:使用的是经过ScriptManager封装后的ajax方法,直接像使用c#后台类那样,
36
//
需要在页面添加 <asp:ScriptManager>服务端控件
37
DClientService.set_defaultSucceededCallback(webSrvCallback);
//
回调函数
38
var _contentObj =
new Object();
//
构造上下文对象
39
_contentObj.name = "wangsh";
40 DClientService.set_defaultUserContext(_contentObj); //
上下文
41
DClientService.DClientDemo("wangsh", 26, 8000.08,
false);
//
调用webservice方法
42
}
43
44 function httpReqCallback() {
45 //
每一个XMLHttpRequest对象AJAX过程中的readyState状态都会发生4次变化,每次变化都触发一个onreadystatechange事件,也就是调用四次该方法
46
//
具体状态值详解请参考:http://www.cn-cuckoo.com/2007/07/16/the-details-for-five-states-of-readystate-9.html
47
if (
this.readyState == 4)
//
请求状态为4表示成功
48
{
49 if (
this.status == 200)
//
http 状态200表示OK
50
{
51 alert( this.responseText);
52 }
53 else
//
http 返回状态失败
54
{
55 alert("服务端返回状态" + this.statusText);
56 }
57 }
58 }
59
60 function webSrvCallback(result, userContext, methodName) {
61 alert("1、操作结果: " + Sys.Serialization.JavaScriptSerializer.serialize(result) + "\n" +
62 "2、上下文: " + Sys.Serialization.JavaScriptSerializer.serialize(userContext) + "\n" +
63 "3、调用的web service方法名: " + methodName);
64 }
65
66 function getXMLHttpRequest() {
67 //
>=IE 7 和 firefox
68
if (window.XMLHttpRequest) {
69 return
new window.XMLHttpRequest();
70 }
71 else {
72 //
Msxml2.XMLHTTP用在高版本的IE5/6,Microsoft.XMLHTTP用在《IE 5
73
var progIDs = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
74
75 for (
var i = 0; i < progIDs.length; i++) {
76 try {
77 var xmlHttp =
new ActiveXObject(progIDs[i]);
78 return xmlHttp;
79 }
80 catch (ex) { }
81 }
82 return
null;
83 }
84 }
85 </script>
86 </head>
87 <body>
88 <div>
89 <br />
90
91 <input type="button" style="width: 150px" value="简单ajax 测试" οnclick="javascript:commAjaxClick()" />
92 <br />
93 <br />
94 </div>
95 <form id="form1" runat="server">
96 <asp:ScriptManager ID="ScriptManager1" runat="server">
97 <Services>
98 <asp:ServiceReference Path="http://localhost/DClientService/DClientService.asmx"
99 InlineScript="false" />
100 </Services>
101 </asp:ScriptManager>
102 </form>
103 </body>
104
第二段代码演示的功能有:
1、如何请求REST协议的服务?
ArcGIS for Server 10.1系列 - 动态获取权限Token
ajax方式 以post请求REST服务
1 function initToken() {
2 var XHR = commClass.get_xmlHttpRequest();
3 if (XHR != null) {
4 // POST方式请求Rest
5 XHR.open("POST", agsTokenUri,
false);
6 XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
7 XHR.onreadystatechange = function () {
8 tokenCallback.apply(XHR);
9 };
10 // IP方式
11 XHR.send("username=wangsh&password=123456&client=referer&referer=" + appUri + "&expiration=1000&f=pjson");
12 // HTTP Referer方式
13
//
XHR.send("username=wangsh&password=123456&client=referer&referer=" + appUri + "&expiration=1000&f=pjson");
14 }
15 XHR = null;
16 }
17
18 /* *
19 * 回调函数
20
*/
21 function tokenCallback() {
22 try {
23 if ( this.readyState == 4)
//
请求状态为4表示成功
24 {
25 if ( this.status == 200)
//
http 状态200表示OK
26 {
27 var _backInfo = eval('(' + this.responseText + ')');
28 var _token = _backInfo.token;
29 if (_token != null) {
30 init(_token);
31 }
32 }
33 else //
http 返回状态失败
34 {
35 alert("服务端返回状态" + this.statusText);
36 }
37 }
38 }
39 catch (ex0) {
40 }
41