<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    孤燈野火
    暢想的天空
    posts - 2,comments - 4,trackbacks - 0


    問題描述

      在jquery或zepto下,循環調用同一個jsonp

      

    復制代碼
     for(var i = 0;i<5;i++){
    $.ajax({
    url:
    'https://m.suning.com/authStatus?callback=checkLogin1&_=1430100870770',
    dataType:
    'jsonp',
    jsonpCallback:
    'checkLogin1',
    success:function(data){
    console.info(
    'success');
    },
    error:function(xhr,e){
    console.error(e);
    }
    });
    }
    復制代碼

      結果

      有些成功有些失敗了?這是為何?

     

    問題解釋

      觀察jsonp的源碼

      

    復制代碼
     /**
    * jsonp請求
    * @param options
    * @param deferred
    * @returns {*}
    */ $.ajaxJSONP = function(options, deferred){
    //未設置type,就走 ajax 讓參數初始化.
    //如直接調用ajaxJSONP,type未設置 if (!('type' in options)) return $.ajax(options)
    var _callbackName = options.jsonpCallback, //回調函數名 callbackName = ($.isFunction(_callbackName) ? _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)), //沒有回調,賦默認回調 script = document.createElement('script'),
    originalCallback
    = window[callbackName], //回調函數 responseData,
    //中斷請求,拋出error事件
    //這里不一定能中斷script的加載,但在下面阻止回調函數的執行 abort = function(errorType) {
    $(script).triggerHandler(
    'error', errorType || 'abort')
    },
    xhr
    = { abort: abort }, abortTimeout
    //xhr為只讀deferred if (deferred) deferred.promise(xhr)
    //監聽加載完,加載出錯事件 $(script).on('load error', function(e, errorType){
    //清除超時設置timeout clearTimeout(abortTimeout)
    //刪除加載用的script。因為已加載完了 $(script).off().remove()
    //錯誤調用error if (e.type == 'error' || !responseData) {
    ajaxError(
    null, errorType || 'error', xhr, options, deferred)
    }
    else {
    //成功調用success ajaxSuccess(responseData[0], xhr, options, deferred)
    }
    //回調函數 window[callbackName] = originalCallback
    if (responseData && $.isFunction(originalCallback))
    originalCallback(responseData[
    0])
    //清空閉包引用的變量值,不清空,需閉包釋放,父函數才能釋放。清空,父函數可以直接釋放 originalCallback = responseData = undefined
    })
    if (ajaxBeforeSend(xhr, options) === false) {
    abort(
    'abort')
    return xhr
    }
    //回調函數設置,給后臺執行 window[callbackName] = function(){
    /* console.info('callbackName arguments ');
    console.info(arguments[0]);
    */ responseData = arguments
    /*console.info('responseData ');
    console.info(responseData);
    */ } //回調函數追加到請求地址 script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName)
    document.head.appendChild(script)
    //超時處理,通過setTimeout延時處理 if (options.timeout > 0) abortTimeout = setTimeout(function(){
    abort(
    'timeout')
    }, options.timeout)
    return xhr
    }
    復制代碼

      問題出在多線程處理。 當第一個jsonp剛執行完callback,賦了值時,此時,script的load事件還未觸發。第二個JSONP開始初始化。然后第一個script的load開始執行,但它的數據已被清掉了

        第一個jsonp剛執行完callback,響應數據賦給了 responseData 

      

    復制代碼
    //回調函數設置,給后臺執行         window[callbackName] = function(){
    /* console.info('callbackName arguments ');
    console.info(arguments[0]);
    */ responseData = arguments
    /*console.info('responseData ');
    console.info(responseData);
    */ }
    復制代碼

     

    第二個JSONP開始初始化。沒錯  responseData又被賦為undefine!!!

      

    第一個script的load開始執行,responseData這時判斷絕對為undefined,為毛?因為這是閉包,引用最后一個responseData的值。只能進入error了。

     

    問題修復

      策略: 

      1, 修改jsonp源碼。在執行callback時,將responseData,傳入監聽函數。諸如function(data){ return function( ...onload... }(responseData);這個太麻煩,而且還得注意開源協議。

      2,規避jsonp的響應。改成這樣一種寫法。原理是,只用jsonp發請求,然后后臺執行window.callback。

    復制代碼
    window.checkLogin1 = function(data){
    console.info(
    'checkLogin1 success');
    console.info(data);
    }
    for(var i = 0;i<5;i++){
    $.ajax({
    url:
    'https://m.suning.com/authStatus?callback=checkLogin1&_=1430100870770',
    dataType:
    'jsonp' }); }
    復制代碼

      切記不能加 jsonpCallback:‘checkLogin1’.原因是,jsonp會重寫window[checkLogin1].第二次請求將找不到。

    復制代碼
    //回調函數設置,給后臺執行         window[callbackName] = function(){
    /* console.info('callbackName arguments ');
    console.info(arguments[0]);
    */ responseData = arguments
    /*console.info('responseData ');
    console.info(responseData);
    */ }
    復制代碼
    posted on 2016-04-14 10:52 孤飛燕 閱讀(238) 評論(0)  編輯  收藏 所屬分類: JSONP

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: a级毛片在线免费| 亚洲成a人片在线观看播放| 免费无码一区二区三区蜜桃大| 最近的中文字幕大全免费版| 成年女人毛片免费视频| 久久精品国产亚洲av麻豆蜜芽 | 亚洲av日韩综合一区在线观看| 亚洲AV中文无码乱人伦下载 | 久久精品国产精品亚洲色婷婷| 91视频免费观看| 亚洲国产人成在线观看69网站| 亚洲成a人无码亚洲成av无码 | 美女露100%胸无遮挡免费观看| www在线观看免费视频| 四虎在线最新永久免费| 日韩一区二区免费视频| 亚洲精品无码午夜福利中文字幕| 亚洲一区二区三区免费视频| 四虎永久在线观看免费网站网址| 成人午夜亚洲精品无码网站| 亚洲一区二区三区在线观看蜜桃| 日韩吃奶摸下AA片免费观看| 亚洲精品乱码久久久久久中文字幕| 免费a级毛片无码a∨免费软件 | 国色精品卡一卡2卡3卡4卡免费| 中日韩亚洲人成无码网站| 国产精品网站在线观看免费传媒| 日韩毛片免费在线观看| 手机永久免费的AV在线电影网| 毛片高清视频在线看免费观看| 青草久久精品亚洲综合专区| 99热在线精品免费全部my| 亚洲AV人无码综合在线观看| AV免费网址在线观看| 免费观看又污又黄在线观看| 免费无码又爽又刺激高潮| 三年在线观看免费观看完整版中文| jjzz亚洲亚洲女人| 午夜亚洲WWW湿好爽| 国产成人免费a在线资源| 亚洲第一第二第三第四第五第六|