<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级视频无风险| 怡红院亚洲红怡院在线观看| 亚洲一级高清在线中文字幕| 亚洲av无码无线在线观看| fc2免费人成在线视频| 99久在线国内在线播放免费观看 | 91亚洲国产成人精品下载| 国产精品亚洲一区二区麻豆| a免费毛片在线播放| 97人妻无码一区二区精品免费| 亚洲国产精品自在拍在线播放 | 青春禁区视频在线观看直播免费| 亚洲福利精品一区二区三区| 亚洲欧洲精品久久| 一二三区免费视频| 国产一卡2卡3卡4卡无卡免费视频| 亚洲深深色噜噜狠狠爱网站 | 免费观看四虎精品成人| 91在线手机精品免费观看| 亚洲国产成人久久综合一区77| 亚洲Av无码一区二区二三区| 三根一起会坏掉的好痛免费三级全黄的视频在线观看 | 夜夜爽妓女8888视频免费观看| 91精品免费国产高清在线| 国产亚洲精品线观看动态图| 亚洲欧洲日产国码久在线| 免费A级毛片在线播放| 亚洲欧洲精品成人久久奇米网| 亚洲中文字幕久久无码| 91精品国产免费| 亚洲午夜无码久久久久| 免费在线观看亚洲| 日韩成人免费视频播放| 色偷偷亚洲女人天堂观看欧| 午夜视频在线免费观看| 国产AV无码专区亚洲AV男同| 日韩免费高清一级毛片| 日韩一区二区免费视频| 亚洲精品欧美综合四区| 成人在线免费观看| 亚洲六月丁香婷婷综合|