自定義jsonp請求數據

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

本文連接:http://www.javashuo.com/article/p-ddvbuyfi-hh.htmlhtml

相關文章
相關標籤/搜索