深入分析DWREngine._sendData

DWREngine._sendData 描述了dwr框架如何发送请求,它的调用栈如下:

--〉DWREngine._execute--DWREngine.endBatch--〉DWREngine._sendData)

/**

* @private Actually send the block of data in the batch object.

*/

DWREngine._sendData = function(batch) {

// If the batch is empty, don't send anything

//通常此时batch.map.callCount为1,在DWREngine._execute++过了

if (batch.map.callCount == 0) return;

// Call any pre-hooks

//如果有任何preHooks,那么进入下面的if块,通常没有

for (var i = 0; i < batch.preHooks.length; i++) {

batch.preHooks[i]();

}

//调用preHooks的函数组后,清空preHooks

batch.preHooks = null;

// Set a timeout

//如果存在timeout且不为0,那么进入下面的if块,通常情况下不存在

if (batch.timeout && batch.timeout != 0) {

batch.interval = setInterval(function() {

clearInterval(batch.interval);

DWREngine._abortRequest(batch);

}, batch.timeout);

}

// A quick string to help people that use web log analysers

//定义一个临时变量存储服务器端的特定路径

var statsInfo;

if (batch.map.callCount == 1) {

statsInfo = batch.map["c0-scriptName"] + "." + batch.map["c0-methodName"] + ".dwr";

}

//通常情况下,不会进入下面的else

else {

statsInfo = "Multiple." + batch.map.callCount + ".dwr";

}

// Get setup for XMLHttpRequest if possible

//设置发送请求的发送请求的客户端,不同浏览器有所不同

if (batch.method == DWREngine.XMLHttpRequest) {

if (window.XMLHttpRequest) {

batch.req = new XMLHttpRequest();

}

// IE5 for the mac claims to support window.ActiveXObject, but throws an error when it's used

else if (window.ActiveXObject && !(navigator.userAgent.indexOf('Mac') >= 0 && navigator.userAgent.indexOf("MSIE") >= 0)) {

batch.req = DWREngine._newActiveXObject(DWREngine._XMLHTTP);

}

}

//定义临时变量存储请求字符串

var query = "";

//定义临时变量存储batch.map的各个属性

var prop;

//如果请求客户端存在,通常是存在的,至少在IEfirefox中是存在的

if (batch.req) {

//设置batch.map.xml

batch.map.xml = "true";

// Proceed using XMLHttpRequest

//如果请求是异步的,通常如此

if (batch.async) {

//设置回调函数即DWREngine._stateChange

batch.req.onreadystatechange = function() {

DWREngine._stateChange(batch);

};

}

// Workaround for Safari 1.x POST bug

//以下代码用于适应Safari浏览器,如果不使用无需关心

var indexSafari = navigator.userAgent.indexOf('Safari/');

if (indexSafari >= 0) {

// So this is Safari, are we on 1.x? POST is broken

var version = navigator.userAgent.substring(indexSafari + 7);

var verNum = parseInt(version, 10);

if (verNum < 400) {

batch.verb == "GET";

}

// else if (verNum <= 417) {

// batch.map.isBrokenSafari2 = "true";

// }

}

//如果以GET方式请求,进入下面的代码段,通常是POSTdwr默认),所以无需关心下面的if

if (batch.verb == "GET") {

// Some browsers (Opera/Safari2) seem to fail to convert the value

// of batch.map.callCount to a string in the loop below so we do it

// manually here.

batch.map.callCount = "" + batch.map.callCount;

for (prop in batch.map) {

var qkey = encodeURIComponent(prop);

var qval = encodeURIComponent(batch.map[prop]);

if (qval == "") {

if (DWREngine._warningHandler) {

DWREngine._warningHandler("Found empty qval for qkey=" + qkey);

}

}

query += qkey + "=" + qval + "&";

}

query = query.substring(0, query.length - 1);

try {

batch.req.open("GET", batch.path + "/exec/" + statsInfo + "?" + query, batch.async);

batch.req.send(null);

if (!batch.async) {

DWREngine._stateChange(batch);

}

}

catch (ex) {

DWREngine._handleMetaDataError(null, ex);

}

}

//默认情况下进入下面的else

else {

//遍历batch.map,将其属性放入请求字符串中

for (prop in batch.map) {

if (typeof batch.map[prop] != "function") {

query += prop + "=" + batch.map[prop] + "\n";

}

}

//发送请求开始

try {

// This might include Safari too, but it shouldn't do any harm

// if (navigator.userAgent.indexOf('Gecko') >= 0) {

//

batch.req.setRequestHeader('Connection', 'close');

// }

//打开连接

batch.req.open("POST", batch.path + "/exec/" + statsInfo, batch.async);

//设置头

batch.req.setRequestHeader('Content-Type', 'text/plain');

//发送

batch.req.send(query);

//如果不是异步那么进入下面的块(即手动调用钩子而不是通过xmlhttprequest的属性)通常是异步所以无需关心下面的代码

if (!batch.async) {

DWREngine._stateChange(batch);

}

}

catch (ex) {

DWREngine._handleMetaDataError(null, ex);

}

}

}

//如果请求的客户端不存在,那么进入下面的else块,通常情况下是存在,所以无需关心下面的代码

else {

batch.map.xml = "false";

var idname = "dwr-if-" + batch.map["c0-id"];

// Proceed using iframe

batch.div = document.createElement('div');

batch.div.innerHTML = "<iframe src='javascript:void(0)' frameborder='0' width='0' height='0' id='" + idname + "' name='" + idname + "'></iframe>";

document.body.appendChild(batch.div);

batch.iframe = document.getElementById(idname);

batch.iframe.setAttribute('style', 'width:0px; height:0px; border:0px;');

if (batch.verb == "GET") {

for (prop in batch.map) {

if (typeof batch.map[prop] != "function") {

query += encodeURIComponent(prop) + "=" + encodeURIComponent(batch.map[prop]) + "&";

}

}

query = query.substring(0, query.length - 1);

batch.iframe.setAttribute('src', batch.path + "/exec/" + statsInfo + "?" + query);

document.body.appendChild(batch.iframe);

}

else {

batch.form = document.createElement('form');

batch.form.setAttribute('id', 'dwr-form');

batch.form.setAttribute('action', batch.path + "/exec" + statsInfo);

batch.form.setAttribute('target', idname);

batch.form.target = idname;

batch.form.setAttribute('method', 'post');

for (prop in batch.map) {

var formInput = document.createElement('input');

formInput.setAttribute('type', 'hidden');

formInput.setAttribute('name', prop);

formInput.setAttribute('value', batch.map[prop]);

batch.form.appendChild(formInput);

}

document.body.appendChild(batch.form);

batch.form.submit();

}

}

};

总结:

DWREngine._sendData封装了ajax发送请求的细节,

特别应该注意

1)它向谁发送请求

batch.req.open("POST", batch.path + "/exec/" + statsInfo, batch.async);

从一个例子看看请求地址(batch.path + "/exec/" + statsInfo)到底是什么

请求地址如下(来自一个真实的例子)

/dwr/exec/CommentService.writeComment.dwr

2)那么除了请求地址外还附带了什么参数呢?

看看batch.req.send(query);

query为如下内容(来自一个真实的例子)

"callCount=1\n

c0-scriptName=CommentService\n

c0-methodName=writeComment\n

c0-id=6906_1152167155406\n

c0-e1=string:\n

c0-e2=string:%E5%85%AC%E5%85%B3%E5%B9%BF%E5%91%8A\n

c0-e3=string:127.0.0.1\n

c0-e4=string:0\n

c0-e6=string:1\n

c0-e7=string:9549815571\n

c0-e8=string:alex\n

c0-e5=Object:{tvUserId:reference:c0-e6,userNo:reference:c0-e7,loginName:reference:c0-e8}\n

c0-e10=string:51764\n

c0-e11=string:HIDBXMOO\n

c0-e9=Object:{videoId:reference:c0-e10,virtualName:reference:c0-e11}\n

c0-param0=Object:{title:reference:c0-e1,content:reference:c0-e2,ip:reference:c0-e3, parentId:reference:c0-e4, user:reference:c0-e5, video:reference:c0-e9}\n

xml=true\n"

你可能感兴趣的:(Ajax,xml,DWR,IE,Safari)