以下分析純屬個人簡潔,不足之處望指教;以下分析在DWR20中,版本不同之處勿怪;
beginBatch():
beginBatch方法在engine.js中出現兩次,一次是_execute()代碼段開始,一處就是方法定義處;
dwr.engine.beginBatch = function() {
if (dwr.engine._batch) {
dwr.engine._handleError(null, { name:"dwr.engine.batchBegun", message:"Batch already begun" });
return;
}
dwr.engine._batch = dwr.engine._createBatch();
};
方法開始執行,dwr.engine._batch初始爲null,因爲if(null)不成立;執行dwr.engine.createBatch()方法;
官方解釋:生成一個標準的batch對象
dwr.engine._createBatch = function() {
var batch = {
map:{
callCount:0,
page:window.location.pathname + window.location.search,
httpSessionId:dwr.engine._getJSessionId(),
scriptSessionId:dwr.engine._getScriptSessionId()
},
charsProcessed:0, paramCount:0,
parameters:{}, headers:{},
isPoll:false, handlers:{}, preHooks:[], postHooks:[],
rpcType:dwr.engine._rpcType, //dwr.engine._rpcType默認是dwr.engine.XMLHttpRequest,值爲1,即通過ajax調用,默認爲異步
httpMethod:dwr.engine._httpMethod,
async:dwr.engine._async,
timeout:dwr.engine._timeout,
errorHandler:dwr.engine._errorHandler,
warningHandler:dwr.engine._warningHandler, //dwr.engine._warningHandler默認調用dwr.engine.debug(message)方法,即控制檯輸出message
textHtmlHandler:dwr.engine._textHtmlHandler //默認爲空;
};
if (dwr.engine._preHook) batch.preHooks.push(dwr.engine._preHook); //_preHook以及_post默認都爲null
if (dwr.engine._postHook) batch.postHooks.push(dwr.engine._postHook);
var propname, data;
if (dwr.engine._headers) { //_headers以及_parameters默認爲null,直接返回batch對象
for (propname in dwr.engine._headers) {
data = dwr.engine._headers[propname];
if (typeof data != "function") batch.headers[propname] = data;
}
}
if (dwr.engine._parameters) {
for (propname in dwr.engine._parameters) {
data = dwr.engine._parameters[propname];
if (typeof data != "function") batch.parameters[propname] = data;
}
}
return batch;
};
生成標準dwr.engine._batch對象如下:
以上屬性均爲默認,除httpSessionId page scriptSessionId對象;
dwr.engine._getJSessionId()方法如下:
/** @private What is our session id? */
dwr.engine._getJSessionId = function() {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
while (cookie.charAt(0) == ' ') cookie = cookie.substring(1, cookie.length);
if (cookie.indexOf(dwr.engine._sessionCookieName + "=") == 0) {
return cookie.substring(dwr.engine._sessionCookieName.length + 1, cookie.length);
}
}
return "";
};
解釋下:1.session是服務器端存儲技術,瀏覽器默認通過發送key爲JSESSIONID的cookie,所以如果瀏覽器禁用了SESSION,還可以通過URL重寫將JSESSIONID寫在地址欄使用SESSION;
2.在tomcat6下可以通過該方法獲取到JSESSIONID,但是在tomcat7下document.cookie無法獲取到JSESSIONID這條cookie,解決方案 tomcat conf目錄下server.xml中對應Context添加useHttpOnly="false"即可,親測可行
dwr.engine._getScriptSessionId()方法如下:
/** The function that we use to fetch/calculate a session id */
dwr.engine._getScriptSessionId = function() {
if (dwr.engine._scriptSessionId == null) {
dwr.engine._scriptSessionId = dwr.engine._origScriptSessionId + Math.floor(Math.random() * 1000);
}
return dwr.engine._scriptSessionId;
};
/** The original page id sent from the server */
dwr.engine._origScriptSessionId = "009659986C0DAED0AE65D2B30BF1FC1E";
所以dwr.engine._getScriptSessionId()爲生成隨機的一串ID標識;
page:window.location.pathname + window.location.search,
dwr.engine._batch.map.Page屬性爲:window.location.pathname爲項目路徑直到?前面值,window.location.search爲?之後參數值;
dwr.engine._debug()方法分析:
--第一個參數爲控制檯輸出信息,第二個參數爲是否打印堆棧信息 調用console.trace()方法;
/** @private Used internally when some message needs to get to the programmer */
dwr.engine._debug = function(message, stacktrace) {
var written = false;
try {
if (window.console) {
if (stacktrace && window.console.trace) window.console.trace();
window.console.log(message);
written = true;
}
else if (window.opera && window.opera.postError) {
window.opera.postError(message);
written = true;
}
}
catch (ex) { /* ignore */ }
if (!written) {
var debug = document.getElementById("dwr-debug");
if (debug) {
var contents = message + "<br/>" + debug.innerHTML;
if (contents.length > 2048) contents = contents.substring(0, 2048);
debug.innerHTML = contents;
}
}
};
調用方法可以默認有兩種DWREngine._debug('我是debug信息',true)或者dwr.engine._debug('我是debug信息');
效果如下:
dwr.engine._handleError()方法如下:
代碼作用:會彈窗提示錯誤信息,兩個參數 batch以及ex. ex爲JS對象,指定message屬性爲彈框提示內容,不指定message屬性的話就提示"A server error has occured."
dwr.engine.defaultErrorHandler = function(message, ex) {
dwr.engine._debug("Error: " + ex.name + ", " + ex.message, true);
if (message == null || message == "") alert("A server error has occured.");
// Ignore NS_ERROR_NOT_AVAILABLE if Mozilla is being narky
else if (message.indexOf("0x80040111") != -1) dwr.engine._debug(message);
else alert(message);
};
通常batch傳入爲null時,調用_errorHandler方法,默認的_errorHandler爲dwr.engine._errorHandler = dwr.engine.defaultErrorHandler;
dwr.engine.defaultErrorHandler = function(message, ex) {
dwr.engine._debug("Error: " + ex.name + ", " + ex.message, true);
if (message == null || message == "") alert("A server error has occured.");
// Ignore NS_ERROR_NOT_AVAILABLE if Mozilla is being narky
else if (message.indexOf("0x80040111") != -1) dwr.engine._debug(message);
else alert(message);
};
實例代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="/DWRDemo/dwr/engine.js"></script>
</head>
<body>
<script type="text/javascript">
window.onload=function(){
dwr.engine._handleError(null, { name:"dwr.engine.invalidRpcType", message:"RpcType must be one of dwr.engine.XMLHttpRequest or dwr.engine.IFrame or dwr.engine.ScriptTag" });
//彈窗提示 message
}
</script>
</body>
</html>
運行效果: