整理代码的时候发现一个之前写的实现jsonp请求方法,放在这里分享一下~
原理:经过js新建script dom对象,利用src携带参数和callback方法,将数据发送至后端,须要后端配合将数据放在callback中返回
功能:能够同时进行多个jsonp请求,且能够设置超时时间
注意:为了保证能够同时进行多个jsonp请求,因此每次请求须要新增script dom对象,请求结束后须要进行销毁javascript
var jsonpId = 0; // 用来标记建立的<script>元素 var debug = true; // 是否开启debug function addScriptTag(src) { var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.setAttribute('src',src); script.setAttribute('onload','try {document.body.removeChild(this);} catch (e) { debug ? console.error(e) : ""; }'); // 用完就删 document.body.appendChild(script); return script; } /* * jsonp 获取数据 跨域 * paramObj { * url: 请求的接口 * timeout: 请求过时时间(设置为0或者不设置这个参数,表示不设置过时时间,默认为0) * data: 要发送的数据 * ready: 请求成功后调用的方法 * error: 请求失败后调用的方法(如:超时) * } * */ function jsonpData(paramObj) { var url = paramObj.url + ((paramObj.url.indexOf('?') > -1) ? '&' : '?') + formatParams(paramObj.data); // 请求数据 var mark = jsonpId++; window.jsonpCallback ? true : window.jsonpCallback = {}; window.jsonpCallback[mark] = function (data) { // 针对每个jsonp请求,生成一个对应的callback方法 clearTimeout(window.timer[mark]); // 清除掉对应的定时器 paramObj.ready ? paramObj.ready(data) : ''; try { // 删除回调方法 delete window.jsonpCallback[mark]; } catch (e) { window.jsonpCallback[mark] = null; } }; var script = addScriptTag(url + "&callback=jsonpCallback[" + mark + "]"); // 请求超时处理 var timeout = paramObj.timeout ? paramObj.timeout : 0; window.timer ? true : window.timer = {}; if(timeout) { window.timer[mark] = setTimeout(function () { if(window.jsonpCallback[mark]) { // 移除对应的script dom,解决当数据超过设置的超时时间后返回了数据,但callback却不存在的状况 try { document.body.removeChild(script); } catch (e) { debug ? console.error(e) : ''; } window.jsonpCallback[mark] = function () { // 从新定义一下回调方法, 改写 callback try { delete window.jsonpCallback[mark]; } catch (e) { window.jsonpCallback[mark] = null; } }; paramObj.error ? paramObj.error('请求超时,请检查网络环境!') : ''; // 超时执行 error // 设置一个足够长的计时器,将上面的回调方法完全删除,若是没有走超时处理的方法,这个计时器也就不会存在 var longTimer = setTimeout(function () { if(window.jsonpCallback[mark]) { // 若是回调方法存在,完全删除 try { delete window.jsonpCallback[mark]; clearTimeout(longTimer); } catch (e) { window.jsonpCallback[mark] = null; } } }, 120000); } clearTimeout(window.timer[mark]); // 清除掉对应的定时器 }, timeout); } }