浏览 4088 次
|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2007-06-23 关键字: Ajax封装,回调函数,接口友好
>>注意:请下载后面(9楼)的v1.1正式版。如果要优先考虑IE7中的Native XHR,请自己把附件中bajax.js文件里的bajax_object函数替换一下(修改的代码在9楼的页面里——不想更新附件了)。
前一段时间写51ditu和动易的集成,现在准备改进成Ajax的。很早以前就知道了Ajax,但一直没有实际用过。 网上Google了一番,看了Sajax.php…… 还是简单点好,自己写了个很小的封装,测试对浏览器的兼容性还不错,并且回调函数的接口比较友好。 另:经测试,发现如果是对同一个XMLHttpReques对象进行多次open、send等操作,IE会有Cache问题,Firefox正常。但如果是每一次都是重新new一个的话,IE就支持得很好了(Firefox自然不用说)。 用这个库(面向用户的其实就一个函数),不用考虑XMLHttpRequest的任何细节,就如同调用和定义普通的Js函数。 用法:
<script language="javascript" src="bajax.js"></script>
<script language="javascript">
function callback(req, id) {
if(req.readyState == 4 && req.status == 200) {
if(id)document.getElementById(id).innerHTML = req.responseText;
//eval(req.responseText);
}
}
</script>
<div id="someid"></div>
<div onClick="bajax_send('http://xxx.net/yourscript.php?xxx', callback, 'someid')">点击查看哦!</div>
附源码内容
var bajax_debug_enable = false;
// 主函数:
//(URL,回调函数,传递给回调函数的附加数据,方法,POST数据,是否异步)
function bajax_send(url, callback, fdata, method, sdata, asyn)
{
fdata = (fdata === undefined)? null: fdata;
method = method || "GET";
sdata = (sdata === undefined)? null: sdata;
asyn = (asyn === undefined)? true: asyn;
var X = new bajax_object();
if(asyn)
X.onreadystatechange = function(){ callback(X, fdata); };
X.open(method, url, asyn);
if(bajax_debug_enable)
bajax_debugger(callback);
X.send(sdata);
if(asyn) return X;
else callback(X, fdata);
}
// 兼容IE与其它浏览器(From Sajax.php v0.12)
function bajax_object()
{
var A;
var _msxmlhttp = new Array(
'Msxml2.XMLHTTP.5.0',
'Msxml2.XMLHTTP.4.0',
'Msxml2.XMLHTTP.3.0',
'Msxml2.XMLHTTP',
'Microsoft.XMLHTTP');
for(var i = 0; i < _msxmlhttp.length; i++) {
try {
if(A = new ActiveXObject(_msxmlhttp[i])) break;
} catch (e) {
A = null;
}
}
if(!A && typeof XMLHttpRequest != "undefined")
A = new XMLHttpRequest();
if(!A)
alert("Could not create connection object.");
return A;
}
// Debug information...
function bajax_debugger(func)
{
var S = func.toString();
alert('[Running] ' + S.slice(9, S.indexOf(')', 10)) + ')');
}
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2007-06-25
呵呵,怎么没人回一哈啊。。。。
自己补充一下: 我不太清楚IE、Firefox或是其它浏览器申请一个XMLHttpRequest对象的开销有多大?因为每个Ajax请求都是申请一个新的XMLHttpRequest对象。这样做的好处是不存在在全局域管理一个XMLHttpRequest对象池之类的东西,各请求对象之间没有冲突,程序好写。不足之处可能就是会有开销的问题(估计问题不大,毕竟OO就是在使用对象嘛,呵呵)。 另外,能够传递一个附加的数据到回调函数中,也是一种极大的方便。比如可以传递一个外部容器的Id,或者一个需要用响应数据操作的对象、甚至可以传递一个数组,以用于与服务器响应数据的复杂操作等。 (创建XMLHttpRequest对象的兼容代码来源于Sajax.php v0.12,在此声明一下。) |
|
| 返回顶楼 | |
|
时间:2007-07-20
快一个月了,想强化一下Ajax的封装——有“对象池管理”的功能。测试时附带验证这个Bajax的POST操作(以前只是使用GET方法)…………呵呵,大跌眼镜——因为没有设置必要的Header,POST是没有成功的!惨
毕竟只是才学啊,Http的请求模型都没得搞明白 现在修正Bug,并且接口完全改了:把POST和GET分作2个独立的函数,直接使用更方便。 >>原始内容删除。请查看/下载后面(9楼)的正式版。 |
|
| 返回顶楼 | |
|
时间:2007-07-20
1. 应该只使用 msxml2.xmlhttp.6.0和3.0,具体原因请搜索IEBlog。
2. 虽然没有仔细看,不过你的代码很有可能会有内存泄露。。。 |
|
| 返回顶楼 | |
|
时间:2007-07-21
hax 写道 1. 应该只使用 msxml2.xmlhttp.6.0和3.0,具体原因请搜索IEBlog。
2. 虽然没有仔细看,不过你的代码很有可能会有内存泄露。。。 不知内存泄漏会出现在哪里? JS是有内存垃圾收集处理功能的。 可能的一种情况是:因为每次都是创建一个新的请求对象(xhr),返回的对象可能被无限期存储起来而没有释放(一个变量被赋值新的对象,原来的那个值是会进入垃圾处理的)。但这应该是应用的问题了。 >>1. 应该只使用 msxml2.xmlhttp.6.0和3.0,具体原因请搜索IEBlog。 bajax_object的代码是从Sajax.php中拷过来的,没仔细研究。查哈看。。 谢谢 |
|
| 返回顶楼 | |
|
时间:2007-07-23
function callback(req, id) {
if(req.readyState == 4 && req.status == 200) {
var _node = document.getElementById(id);
if(_node) _node.innerHTML = 'Hai ' + req.responseText;
// clear the reference
req.onreadystatechange = null;
}
}
注意我加的那句,没有这句,在IE6下会有内存泄漏。 |
|
| 返回顶楼 | |
|
时间:2007-07-23
BTW,实际上面还不是最严谨,因为出错的时候也应该置为null。
|
|
| 返回顶楼 | |
|
时间:2007-07-23
不了解 MS 的 ActiveXObject,看来真是有些特别
得改一下回调函数的格式约定了,呵呵
function callback(req, id)
{
if(req.readyState == 4) {
if(req.status != 200) {
// do some thing.
req.onreadystatechange = null;
}else{
var _node = document.getElementById(id);
if(_node) _node.innerHTML = 'Hai ' + req.responseText;
// clear the reference
req.onreadystatechange = null;
}
}
}
谢谢hax给予如此详细的指正。 |
|
| 返回顶楼 | |
|
时间:2007-07-23
唉。。。。干脆彻底改一下,用OO封装得了。(谢谢hax提供的修补)
以下为Bajax的正式版,呵呵 用法:
<script language="javascript" src="bajax.js"></script>
<script language="javascript">
function callback(req, id) {
var _node = document.getElementById(id);
// 直接使用req的响应值
if(_node) _node.innerHTML = 'Hai ' + req.responseText;
}
var _obj = new Bajax();
</script>
<div id="someid"></div>
<div onClick="_obj.get('/script.php?name=Liner', callback, 'someid')">GET方法</div>
<div onClick="_obj.post('/script.php', 'name=Liner', callback, 'someid')">POST方法</div>
源代码:
/** bajax.js
* Base Ajax 简易封装 2007.07.20
* ---------------------------------------------------------------------------
* >>接口:
* get, post 常用普通接口。
* e_handler 出错处理句柄,可选。
* _object 创建浏览器兼容XHR的包装。
*
* >>参数:
* @url: 请求的响应页面;
* @sdata: POST的数据;
* @callback: 处理响应数据的回调函数;
*
* 以下参数可选
* @fdata: 传递给回调函数的数据,默认null;
* @asyn: 是否异步,默认true。
*
* 返回值:
* 如果是异步,返回异步请求对象;否则不返回。
*
* >>回调函数:
*
* 回调函数有两个参数:(req, data)
* @req: 异步请求对象(XMLHttpRequest 或 ActiveXObject)
* @data: 传入的附加数据。
*
* >>注意:
*
* 1、传递到回调函数的附加数据可以是数值、字串、数组或对象。
* 2、可置e_handler的参数为null来取消出错处理。
*
* @Author: Tubz.
* @Copyright: GNU - LGPL.
* ---------------------------------------------------------------------------
*/
function Bajax()
{
// 默认出错处理
this._eh = Bajax._error;
}
// 调试设置
Bajax.debug_enable = false;
//-- 用户接口 -----------------------------------------------------------------
// GET 请求
//(URL, 回调函数[, 回调函数附加数据, 是否异步])
Bajax.prototype.get = function (url, callback, fdata, asyn)
{
fdata = (fdata === undefined)? null: fdata;
asyn = (asyn === undefined)? true: asyn;
var _self = this;
var X = Bajax._object();
if(asyn)
X.onreadystatechange = function()
{ Bajax._callback(X, callback, fdata, _self); };
X.open('GET', url, asyn);
if(Bajax.debug_enable)
Bajax._debugger(callback);
X.send(null);
if(asyn){
return X;
}else{
Bajax._callback(X, callback, fdata, _self);
}
}
// POST 请求
//(URL, POST数据, 回调函数[, 回调函数附加数据, 是否异步])
Bajax.prototype.post = function (url, sdata, callback, fdata, asyn)
{
fdata = (fdata === undefined)? null: fdata;
asyn = (asyn === undefined)? true: asyn;
var _self = this;
var X = Bajax._object();
if(asyn)
X.onreadystatechange = function()
{ Bajax._callback(X, callback, fdata, _self); };
X.open('POST', url, asyn);
if(Bajax.debug_enable)
Bajax._debugger(callback);
X.setRequestHeader('Content-length', sdata.length);
X.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
X.send(sdata);
if(asyn){
return X;
}else{
Bajax._callback(X, callback, fdata, _self);
}
}
// 设置出错处理函数
Bajax.prototype.e_handler = function (func)
{
if(func !== undefined) this._eh = func;
}
// 创建一个兼容的XHR对象。
// 改了一下:IE7中优先采用Native XHR
Bajax._object = function()
{
var A;
if(typeof XMLHttpRequest != 'undefined') {
A = new XMLHttpRequest();
}else{
var _msxmlhttp = new Array(
'Msxml2.XMLHTTP.6.0',
'Msxml2.XMLHTTP.3.0',
'Msxml2.XMLHTTP',
'Microsoft.XMLHTTP');
for(var i = 0; i < _msxmlhttp.length; i++) {
try {
if(A = new ActiveXObject(_msxmlhttp[i])) break;
} catch (e) {
A = null;
}
}
}
if(!A)
alert("Could not create connection object.");
return A;
}
//-- 私有函数 -----------------------------------------------------------------
Bajax._callback = function (req, callback, data, obj)
{
if(req.readyState == 4) {
if(req.status != 200) {
//req.onreadystatechange = null;
if(obj._eh) obj._eh(req, callback);
}else{
callback(req, data);
//req.onreadystatechange = null;
}
}
}
// Debug: 显示采用的回调函数。
Bajax._debugger = function (func)
{
alert('running: ' + Bajax._fname(func));
}
// 默认的出错处理
Bajax._error = function (req, callback)
{
alert(req.statusText + '\nShould run: ' + Bajax._fname(callback));
}
// 提取函数名(含参数)
Bajax._fname = function (func)
{
var S = func.toString();
return S.slice(9, S.indexOf(')', 10)) + ')';
}
//-- End.----------------------------------------------------------------------
注:v1.0版在IE中可能会有些问题,同时异步时出错抛出的异常难以处理。请用v1.1。 |
|
| 返回顶楼 | |
|
时间:2007-07-24
不好意思,请教hax:
按照你的说法:req.onreadystatechange = null; 但是这行代码在IE6中会出现运行时错误提示(Firefox中正常),何解? 这样的代码应该不是纸上谈兵吧。谢了。 |
|
| 返回顶楼 | |




