高效地获取XMLhttp对象
来源:Ruby's Louvre 发布时间:2010-01-19 13:49:00
web2.0的标志是Ajax的异步通信的发掘,给我们带来像google map,google suggest 这样令人惊叹的东西。而Ajax的核心就是那个XMLhttp对象(当然,如果用iframe也可以模拟出来,但不在本文议题之内)。
像往常一样,IE发明了东西,然后被标准浏览器抄去,发扬光大了,IE的却不如那么冒牌货,如IE的innerHTML,私自去掉空白,IE的TextRange,只能操作文本,W3C却更为强悍,虽然没什么人用,IE的eot字体技术,W3C则有@font-face……IE的XMLhttp对象也是这样,它是一个为人诟病的ActiveXObject,更要病的是它版本太多了,Msxml2.XMLHTTP.6.0,Msxml2.XMLHTTP.5.0,Msxml2.XMLHTTP.4.0,Msxml2.XMLHTTP.3.0,Msxml2.XMLHTTP,Microsoft.XMLHTTP,越新的版本功能越多,这还不算上IE7的原生XMLHttpRequest对象,IE8的XDomainRequest。W3C那边不管这么多,名字都是固定的,只要升级浏览器就好了。这样就搞得IE那边分支庞大,而且IE一方都是老不死,国内学校里面还有大批window 2000在服役,换言之,IE5.5也不能无视。如何获得创建ActiveXObject的ProgID是重中之重中。问题是,里面也有陷阱,下面是正确的创建XMLHttp对象的ProgID数组:
var xmlhttp_progids = ["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP", "Microsoft.XMLHTTP" ];
//如果用我的超级数组对象,就能很简单地找出正确的xmlhttp_progid
var xmlhttp_progid = dom.array( xmlhttp_progids).one(function(v){
return new ActiveXObject(v)
});
alert(xmlhttp_progid)
撇开我的超级数组不谈,明显当中可供选择的ProgID少许多,像Msxml2.XMLHTTP.5.0,Msxml2.XMLHTTP.4.0不见了。为什么呢?且听我一一道来。可能大家在网上还看到Msxml2.XMLHTTP.7.0,很遗念,那只是以讹传讹,我用IE8测试并不存在这个版本。Msxml2.XMLHTTP.5.0,Msxml2.XMLHTTP.4.0根据我手头上掌握的资料,它们并不是浏览器用的,属于旁支,存在一定的兼容问题。其中5.0是为office所开发的,甚至带有一些特性是后来的6.0所没有的(如xml数字加密)。
MSXML 4.0 is a separate download that was released by Microsoft in October 2001. The latest or current service pack release of MSXML 4.0 is available through the Microsoft Web site. MSXML 4.0 must be installed separately and is not currently included with other Microsoft products. MSXML 4.0 installs side-by-side with earlier versions of MSXML without affecting any existing functionality.
MSXML 5.0 for Microsoft Office Applications is only available with current versions of Microsoft Office. MSXML 5.0 for Microsoft Office Applications installs side-by-side with earlier versions of MSXML without affecting any existing functionality.
那Msxml2.XMLHTTP.3.0是怎么回事呢?根据IE blog的建议,应该仅使用6.0和3.0,不要使用老的microsoft.xmlhttp,那它也应该出现上面的数组中。此外还有一个MSXML2.XMLHTTP.2.6,但不知咋搞的,总之,如果你的游览器打了某些升级补丁,new ActiveXObject("Msxml2.XMLHTTP") 调用的是2.6或3.0版本,非常混乱。此后的版本,才正确对应它的版本号。因此这里没有列举MSXML2.XMLHTTP.2.6与MSXML2.XMLHTTP.3.0的必要,都给Msxml2.XMLHTTP代表了。
在IE7中,微软决定支持W3C的XMLHttp对象,其实是换了外套而已,它是基于3.0版。不过它出于安全的考量,它不允许访问相对路径下的本地文件系统。
从各大类库的情形看来,Msxml2.XMLHTTP.6.0没有什么用到,因为如果微软真的沿着沿着W3C的路线的话,那么IE8中的原生XMLHttp对象应该自动调用Msxml2.XMLHTTP.6.0(它给XMLHttpRequest代表了,三个代表的思想影响深远啊)。下面是几大类库的源码:
//*********************jQuery1.4a2******************
xhr: function(){
return window.ActiveXObject ?
new ActiveXObject("Microsoft.XMLHTTP") :
new XMLHttpRequest();
},
//*********************mootools1.2.4******************
Browser.Request = function(){
return $try(function(){
return new XMLHttpRequest();
}, function(){
return new ActiveXObject('MSXML2.XMLHTTP');
}, function(){
return new ActiveXObject('Microsoft.XMLHTTP');
});
};
//***********************prototype1.61rc2*******************
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
},
不过我的也不赖,结合我的缓存系统更为强悍,这样以下生成XMLhttp对象就不用检测该用何种生成方式,直接从缓存里找就是:
var xhr = function(){
if(!arguments.callee.single){
arguments.callee.single = true;
var fn =dom.array(function(){return new XMLHttpRequest()},//IE7,IE8,w3c
function() {return new ActiveXObject('Msxml2.XMLHTTP')},//IE6
function() {return new ActiveXObject('Microsoft.XMLHTTP')}).one(function(fn){//IE5
return fn();
});
dom.cache("dom-xhr","dom-xhr",fn);//缓存生成XMLHttp对象的函数
return fn();
}else{
return dom.cache("dom-xhr","dom-xhr")();//从缓存获取生成XMLHttp对象
}
}
var xhrObject = xhr();//调用
alert(xhrObject)//[object XMLHttpRequest]
如果不用我的超级数组对象,这里也提供一种原始的方式:
var xhr = function() {
if(!arguments.callee.single){
var fns = [
function () { return new XMLHttpRequest(); },
function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
];
for (var i = 0,n=fns.length; i < n; i++) {
try {
fns[i]();
arguments.callee.single = fns[i];
break;
}catch(e){}
}
return arguments.callee.single();
}else{
return arguments.callee.single();
}
}
var xhrObject = xhr();//调用
alert(xhrObject) //[object XMLHttpRequest]
但即使我们缓存了生成方式,每次还要判断一下arguments.callee.single的值,能否写得更优雅更有效率呢?!能,见我《随性函数》一文。
var xhr = function(){
xhr = dom.array(function(){return new XMLHttpRequest()},//IE7,IE8,w3c
function() {return new ActiveXObject('Msxml2.XMLHTTP')},//IE6
function() {return new ActiveXObject('Microsoft.XMLHTTP')}).one(function(fn){//IE5
return fn();
});
return xhr();
}
//****************或者****************
var xhr = function() {
var fns = [
function () { return new XMLHttpRequest(); },
function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
];
for (var i = 0,n=fns.length; i < n; i++) {
try {
fns[i]();
xhr = fns[i];//注意这里,用于重置函数
break;
}catch(e){}
}
return xhr()
}
我们可以测试一下,在中间加一个alert,看它有没有重复检测生成函数。
XDomainRequest不讨论,资料太少,跨域现在方法很多,CSS跨域,图片跨域,动态script标签,window.name……本文已完美地解决了原议题,利用隋性函数设计了一个高效获取XMLhttp对象的方法,本文就到此为止了。


猜你喜欢
- 什么是正则表达式?正则表达式(Regular Expression)通常被用来检索、替换那些符合某个模式(规则)的文本。此处的Regular
- 乍一听有点蒙,之前用ng和react时也写过类似的功能,但是很顺利(所以忘记具体细节了)。jquery为啥会不行呢?看了一下具体场景,发现原
- 如下所示:# 选取等于某些值的行记录 用 == df.loc[df['column_name'] == some_value
- 如:>>> print ord('a') 97 >>> print chr(97) a
- 我就废话不多说了,直接上代码了。非常简单哦!pytorch转成longtensorb = torch.rand(3,3)#得到的是float
- 本文实例为大家分享了Tensorflow之MNIST CNN实现并保存、加载模型的具体代码,供大家参考,具体内容如下废话不说,直接上代码#
- 本文总结分析了selenium2.0中常用的python函数。分享给大家供大家参考,具体如下:新建实例driver = webdriver.
- 本文实例讲述了python实现批量获取指定文件夹下的所有文件的厂商信息的方法。分享给大家供大家参考。具体如下:功能代码如下:import o
- 可以通过浏览器在访问者的硬盘上创建文件,因为我开始试了一下真的可以,不信你把下面这段代码COPY到一个HTML文件当中再运行一下! <
- 如何远程注册DLL?试试下面的代码:<% Response.Buffer = True %&g
- CSS3的box-shadow属性可以让我们轻松实现图层阴影效果。我们来实战详解一下这个属性。1. box-shadow属性的浏览器兼容性先
- 1.什么是SQL注入 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL
- 一直都在网上抄别人写的电话,邮箱正则表达式,今天稍微有点闲情,把一直想自己写个这样的表达式的心愿给完成:/** * 邮箱地址正则表
- 最近在写测试平台,需要实现一个节点服务器的api,正好在用django,准备使用djangorestframework插件实现。需求实现一个
- 项目进行到和服务器交互,通过post访问服务器端jsp,jsp访问服务器端mysql数据库,最终返回到客户端的中文出现乱码问题。在整个流程中
- 本文实例讲述了Python多层装饰器用法。分享给大家供大家参考,具体如下:前言Python 的装饰器能够在不破坏函数原本结构的基础上,对函数
- XHTML规范中有一条标准就是“每个XHTML标签都有一个结束标记”。那么对于HTML中原来不带结束标记的元素,则在该结束前加上“/”来关闭
- 方法1: 用SET PASSWORD命令 首先登录MySQL。 格式:mysql> set password for 用户名@loca
- 你是否发现,在浩如烟海的应用程序堆里,具有漂亮图标和清爽名字的 App 更容易被用户喜爱。作为开发者,面对这自己的作品,能否自问一句:“从图
- ASP日期和时间函数我们经常会用到,本文列出了12个常用的asp日期和时间函数的语法及用法以作备忘!1.Now Now() 取