JSONP does not support circular calls

Source: Internet
Author: User

Problem description

Under jquery or Zepto, the same jsonp is called in a loop

  

  for(vari =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);    }        }); }

  Results

Some successes, some failures? Why is this?

Explanation of the problem

Observe the source code of JSONP

  

 /** * JSONP Request * @param options * @param deferred * @returns {*}*/$.ajaxjsonp=function (options, deferred) {//without setting the type, go to Ajax and let the parameters initialize. //such as direct call Ajaxjsonp,type not set        if(! ('type' inchOptions))return$.ajax (Options)var_callbackname = Options.jsonpcallback,//callback function nameCallbackname = ($.isfunction (_callbackname)?_callbackname (): _callbackname)|| ('Jsonp'+ (++jsonpid)),//no callback, assign default callbackScript = Document.createelement ('Script'), Originalcallback= Window[callbackname],//callback functionResponseData,//Interrupt request, throw Error event//This does not necessarily interrupt script loading, but prevents the execution of the callback function belowAbort =function (ErrorType) {$ (script). Triggerhandler ('Error', ErrorType | |'Abort')}, XHR={abort:abort}, Aborttimeout//XHR is read-only deferred        if(deferred) deferred.promise (XHR)//Load Error event when monitoring is loaded$ (script). On ('Load Error', Function (e, errorType) {//Purge Timeout setting timeoutcleartimeout (aborttimeout)//Delete the script that was loaded. Because it's finished loading .$ (script). Off (). Remove ()//Wrong call error            if(E.type = ='Error'|| !responsedata) {Ajaxerror (NULL, ErrorType | |'Error', XHR, Options, deferred)} Else {                //successfully called successAjaxsuccess (responsedata[0], XHR, Options, deferred)}//callback functionWindow[callbackname] =Originalcallbackif(ResponseData &&$.isfunction (Originalcallback)) Originalcallback (responsedata[0])            //clears the value of the variable referenced by the closure, does not empty, and the parent function can be freed if the closure is released. Empty, the parent function can be released directlyOriginalcallback = ResponseData =undefined}) if(Ajaxbeforesend (XHR, options) = = =false) {Abort ('Abort')            returnXHR}//callback function settings, for background executionWindow[callbackname] =function () {/*console.info (' callbackname arguments '); Console.info (Arguments[0]);*/ResponseData=arguments/*console.info (' responsedata '); Console.info (responsedata);*/        }        //the callback function is appended to the request addressSCRIPT.SRC = Options.url.replace (/\? +)=\?/,'? $1='+callbackname) document.head.appendChild (script)//time-out processing via settimeout delay processing        if(Options.timeout >0) Aborttimeout =setTimeout (function () {Abort ('Timeout')}, Options.timeout)returnXHR}

The problem is with multithreading. When the first JSONP has just finished executing callback and assigned a value, the script's Load event has not yet been triggered. The second JSONP begins to initialize. Then the load of the first script starts executing, but its data is cleared out.

The first JSONP just finished executing callback, and the response data was assigned to ResponseData

  

// callback function settings, for background execution        Window[callbackname] = function () {          /*  console.info (' callbackname arguments ');            Console.info (Arguments[0]); */              = arguments            /*console.info (' responsedata ');            Console.info (responsedata); */         }

The second JSONP begins to initialize. Yes, ResponseData was again assigned to undefine!!!.

  

The load of the first script begins to execute, responsedata at this point is absolutely undefined, for Mao? Because this is a closure, the value of the last ResponseData is referenced. can only enter the error.

Problem fix

  Policy :

1, modify the JSONP source code. When the callback is executed, the ResponseData is passed into the listener function. such as function (data) {return function (.... onload ...} (responsedata); This is too cumbersome, and you have to pay attention to the open source protocol.

2, avoid the response of JSONP. Changed to such a way of writing. The principle is that the request is made only with JSONP, and then the Window.callback is executed in the background.

 window.checklogin1 =  '  

Remember not to add Jsonpcallback: ' checkLogin1 '. The reason is that JSONP overrides Window[checklogin1]. The second request will not be found.

// callback function settings, for background execution        Window[callbackname] = function () {          /*  console.info (' callbackname arguments ');            Console.info (Arguments[0]); */              = arguments            /*console.info (' responsedata ');            Console.info (responsedata); */         }

JSONP does not support circular calls

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.