整理代碼的時候發現一個之前寫的實現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); } }