跨域的异步请求四
本文将一种崭新的为JSONP添加onerror事件的跨浏览器解决方案。由于ie6~8及opera的script标签不支持onerror事件,因此一般的类库(包括jquery,及其他我所看到的库)也无法处理它们的JSONP的onerror回调(下称负向回调)。难道就没有办法吗?经笔者发现,JSONP的回调函数(下称正向回调)总是在script的onload事件(IE为onreadystatechange)之前就被调用了。因此我们在正向回调执行之时,为script标签添加一个属性,然后待到onload发生时,再检测有没有这个属性就可以判定是否请求成功,没有成功当然就调用我们的负向回调了!
//2011.2.13 by 司徒正美 ;;;( function (WIN,DOM,undefined){ var _dom = WIN.dom, slice = Array.prototype.slice, dom = { mix : function (target, source ,override) { var i, ride = (override === void 0) || override; for (i in source) { if (ride || !(i in target)) { target[i] = source[i]; } } return target; }, noConflict: function ( ) { //防止命名冲突,请先行引用其他库再引用本框架 WIN.dom = _dom; //这是别人的 return dom; //请赋以其一个命名空间 }, jsonp: function (){ var self = arguments.callee, args = self.args(arguments), url = args[0], data = args[1], callback = args[2], errback = args[3], jsonpkey = args[4], jsonpname = "callback" +1* new Date, jsonpval = "dom.jsonp." +jsonpname, add = /\?/.test( url ) ? "&" : "?" , script = DOM.createElement( "script" ), query =[]; data[jsonpkey] = jsonpval self[jsonpname] = function (json){ script.jsonp = 1; callback(json); } for ( var i in data){ query.push(i + "=" +data[i]) } url = url + add + query.join( "&" ) script.src = url; script.onload = script.onreadystatechange = function (){ if ( -[1,] || /loaded|complete/i.test( this .readyState)){ self.removeScript( this ,errback,jsonpname); } } script.onerror = function (){ self.removeScript( this ,errback,jsonpname); } var head = DOM.getElementsByTagName( "head" )[0]; head.appendChild(script); } } dom.mix(dom.jsonp, { args : function (obj){ var array = slice.call(obj) if (array.length === 1){ obj = array[0] array = [obj.url,obj.data,obj.callback,obj.errback,obj.jsonpkey] } if ( typeof array[1] === "function" ){ array.splice(1,0,{}); //让正向回调回到其正确位置 } if ( typeof array[3] !== "function" ){ array.splice(3,0, function (){}); //让负向回调回到其正确位置 } array[4] = array[4] || "jsoncallback" ; return array; }, removeScript: function (script,error,jsonpname){ if ( typeof script.jsonp === "undefined" ){ error(); } if (script.clearAttributes) { script.clearAttributes(); } else { script.onload = script.onreadystatechange = script.onerror = null ; } script.parentNode.removeChild(script); delete this [jsonpname]; } }); window.dom = dom; })( this , this .document); |
dom.jsonp.args会对dom.jsonp的参数进行了重写,因此dom.jsonp支持多种传参方式:
dom.jsonp(url,args,callback,errback,jsonpkey) dom.jsonp(url,callback,errback,jsonpkey) dom.jsonp(url,callback,jsonpkey) dom.jsonp(url,callback) dom.jsonp({ url: '' , callback: function (){} //其他..... }) |
使用示例:
dom.jsonp( "http://del.icio.us/feeds/json/fans/stomita" , function (json){alert(json)}, "callback" ); |
下面例子请用firebug查看请求状态与结果!
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2010-02-13 kangax 的javascript谜题