/**
* @file transport.js
* @description 用于支持AJAX的传输类。
* @author ECShop R&D Team ( http://www.ecshop.com/ )
* @date 2007-03-08 Wednesday
* @license Licensed under the Academic Free License 2.1 http://www.opensource.org/licenses/afl-2.1.php
* @version 1.0.20070308
**/
var Transport =
{
/* *
* 存储本对象所在的文件名。
*
* @static
*/
filename : "transport.js",
/* *
* 存储是否进入调试模式的开关,打印调试消息的方式,换行符,调试用的容器的ID。
*
* @private
*/
debugging :
{
isDebugging : 0,
debuggingMode : 0,
linefeed : "",
containerId : 0
},
/* *
* 设置调试模式以及打印调试消息方式的方法。
*
* @public
* @param {int} 是否打开调试模式 0:关闭,1:打开
* @param {int} 打印调试消息的方式 0:alert,1:innerHTML
*
*/
debug : function (isDebugging, debuggingMode)
{
this.debugging =
{
"isDebugging" : isDebugging,
"debuggingMode" : debuggingMode,
"linefeed" : debuggingMode ? "
" : "\n",
"containerId" : "dubugging-container" + new Date().getTime()
};
},
/* *
* 传输完毕后自动调用的方法,优先级比用户从run()方法中传入的回调函数高。
*
* @public
*/
onComplete : function ()
{
},
/* *
* 传输过程中自动调用的方法。
*
* @public
*/
onRunning : function ()
{
},
/* *
* 调用此方法发送HTTP请求。
*
* @public
* @param {string} url 请求的URL地址
* @param {mix} params 发送参数
* @param {Function} callback 回调函数
* @param {string} ransferMode 请求的方式,有"GET"和"POST"两种
* @param {string} responseType 响应类型,有"JSON"、"XML"和"TEXT"三种
* @param {boolean} asyn 是否异步请求的方式
* @param {boolean} quiet 是否安静模式请求
*/
run : function (url, params, callback, transferMode, responseType, asyn, quiet)
{
/* 处理用户在调用该方法时输入的参数 */
params = this.parseParams(params);
transferMode = typeof(transferMode) === "string"
&& transferMode.toUpperCase() === "GET"
? "GET"
: "POST";
if (transferMode === "GET")
{
var d = new Date();
url += params ? (url.indexOf("?") === - 1 ? "?" : "&") + params : "";
url = encodeURI(url) + (url.indexOf("?") === - 1 ? "?" : "&") + d.getTime() + d.getMilliseconds();
params = null;
}
responseType = typeof(responseType) === "string" && ((responseType = responseType.toUpperCase()) === "JSON" || responseType === "XML") ? responseType : "TEXT";
asyn = asyn === false ? false : true;
/* 处理HTTP请求和响应 */
var xhr = this.createXMLHttpRequest();
try
{
var self = this;
if (typeof(self.onRunning) === "function" && !quiet)
{
self.onRunning();
}
xhr.open(transferMode, url, asyn);
if (transferMode === "POST")
{
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
if (asyn)
{
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4)
{
switch ( xhr.status )
{
case 0:
case 200: // OK!
/*
* If the request was to create a new resource
* (such as post an item to the database)
* You could instead return a status code of '201 Created'
*/
if (typeof(self.onComplete) === "function")
{
self.onComplete();
}
if (typeof(callback) === "function")
{
callback.call(self, self.parseResult(responseType, xhr), xhr.responseText);
}
break;
case 304: // Not Modified
/*
* This would be used when your Ajax widget is
* checking for updated content,
* such as the Twitter interface.
*/
break;
case 400: // Bad Request
/*
* A bit like a safety net for requests by your JS interface
* that aren't supported on the server.
* "Your browser made a request that the server cannot understand"
*/
alert("XmlHttpRequest status: [400] Bad Request");
break;
case 404: // Not Found
alert("XmlHttpRequest status: [404] \nThe requested URL "+url+" was not found on this server.");
break;
case 409: // Conflict
/*
* Perhaps your JavaScript request attempted to
* update a Database record
* but failed due to a conflict
* (eg: a field that must be unique)
*/
break;
case 503: // Service Unavailable
/*
* A resource that this request relies upon
* is currently unavailable
* (eg: a file is locked by another process)
*/
alert("XmlHttpRequest status: [503] Service Unavailable");
break;
default:
alert("XmlHttpRequest status: [" + xhr.status + "] Unknow status.");
}
xhr = null;
}
}
if (xhr != null) xhr.send(params);
}
else
{
if (typeof(self.onRunning) === "function")
{
self.onRunning();
}
xhr.send(params);
var result = self.parseResult(responseType, xhr);
//xhr = null;
if (typeof(self.onComplete) === "function")
{
self.onComplete();
}
if (typeof(callback) === "function")
{
callback.call(self, result, xhr.responseText);
}
return result;
}
}
catch (ex)
{
if (typeof(self.onComplete) === "function")
{
self.onComplete();
}
alert(this.filename + "/run() error:" + ex.description);
}
},
/* *
* 如果开启了调试模式,该方法会打印出相应的信息。
*
* @private
* @param {string} info 调试信息
* @param {string} type 信息类型
*/
displayDebuggingInfo : function (info, type)
{
if ( ! this.debugging.debuggingMode)
{
alert(info);
}
else
{
var id = this.debugging.containerId;
if ( ! document.getElementById(id))
{
div = document.createElement("DIV");
div.id = id;
div.style.position = "absolute";
div.style.width = "98%";
div.style.border = "1px solid #f00";
div.style.backgroundColor = "#eef";
var pageYOffset = document.body.scrollTop
|| window.pageYOffset
|| 0;
div.style.top = document.body.clientHeight * 0.6
+ pageYOffset
+ "px";
document.body.appendChild(div);
div.innerHTML = "