Analysis of how JS Framework realizes the Kissy of Jsonp

Source: Internet
Author: User
Tags call back getscript

Preparation before you begin

Introduction to the principle of jsonp (knowledge of the students as a reviewthe limitations of the same-origin policy let programmers think of cross-domain requests with <script> that are not affected by the same Origin policy. The simple JSON data is just data, loaded into the page by <script> does not make any sense, so a variable is required as the function name, that is, "P", and then the JSON data is passed as a function parameter. After the browser has finished loading, the function executes. Therefore, this function must be a dynamically created global variable. And Jsonp is actually the dynamic loading JS script. To pass a variable to the backend, we need a parameter, often with Jsonp,jsonpcallback,callback, which requires back-end mates, of course. In addition, XHR2 Cors supports cross-domain, you can see here  Introduction to the implementation process of JS Library Ajax modulethe whole is divided into three parts, XHR object, transmitter transport, converter converters. The first is to create a Xhr object, or it might be a pseudo-xhr created by a programmer to implement XHR2 most of the interfaces in each browser, but in any case, the beginning must first create a XHR object. After the request is sent to the server side as a form or script, there is a concept of a transporter, which is responsible for sending the request, depending on the situation, using a different transmitter. Then we need to convert the returned data into the form required by the programmer, which requires a translator. Kissy Framework-related knowledge (just a little bit more. ) util.js: A module of Kissy, which may be called utils more suitable, it mainly provides some auxiliary functions commonly used by Kissy framework. Auxiliary functions are important for a framework, such as Each,filter,isarray, which are common helper functions. There is Util.parsejson related to this blog, I think it is very important, do not know why Kissy 5.0 officially provided by the API does not have this, but I found the source on GitHub, Util/lib/util/json.js here can be seen. In addition to the util.mix commonly used in the following is very interesting, it can add a whitelist, the properties of the copied object in the whitelist will be copied, underscore also have a similar parameter is used for the blacklist. (Wu bei that because of the different use of the scene, the efficiency of the two ways will be different, so util this should not be any improvement, purely to and underscore not the same (if I was wrong, please leave a message light education ... )     event-custom.js: Custom events Glow in the hands of JQuery, the industry Giant (Jquery.on), Kissy naturally. Is Event-custom this kissy module. It uses the PubSub mode (which is actually the observer pattern), a custom event type release (PUB) to multiple callback function subscriptions (SUB) responsible for event handling, and a callback when the event is triggered. The pubsub pattern is used to handle asynchronous events like this, but it has nothing to do with asynchrony, it is synchronous, and custom events do not enter the JS event Loop. Node is very fond of this pattern, the Eventemitter object of events is the PubSub mode, I use it to do a simple test.           
var events = require ("events"); var New events. Eventemitter (); var false ; Emitter.on (function() {     console.assert (async);}); Emitter.emit (// Error false = = Truetrue;
View Code

Then there is the asynchronous implementation of the SetTimeout

var false ; setTimeout (function() {     // no error }, 0true;
View Code  Promise: Kissy's Promise module is the promise/a+ specification, which is an iterative version of promise/a. Promise can let the Ajax-rich pages call back the Pyramid nightmare, but also can make JS programmer easy to use asynchronous to ~ specifically not here to tell.   Bodyfirst we need to make clear the JSONP implementation of a few steps, also mentioned in the introduction, first generate a URL, and then generate a scirpt tag to send the request, and then convert the data out, the final callback. so next, I'll take a look at the code implemented by Kissy Jsonp .directly on Io.jsonp (URL, data, callback)we found the Kissy IO module on GitHub, first of all io.js, to see these commonjs-style
var serializer = require ('./io/form-serializer '); var IO = require ('./io/base '); var util = require (' util '); require ('./io/xhr-transport '); require ('./io/ Script-transport '); require ('./io/jsonp '); require ('./io/form '); require ('./io/ Iframe-transport '); require ('./io/methods ');
View Code

can see xhr-transport,script-transport,iframe-transport this is loading various conveyors, we need to be aware that SCRIPT-TRANSPORT,JSONP will use it. The base.js is the basis of the IO module. We're going to see it later. This API naturally calls Io, as Jquery.get is actually a shorthand for jquery.ajax. See how it performs,              
function (URL, data, callback) {       if (typeof data = = = ' function ') {       = DATA;
     = undefined;       }        return get (URL, data, callback, ' Jsonp ')}

GetScript:require.load

            
function get (URL, data, callback, DataType, type) {//  data parameter can omit if (typeof data = = =) function ') {    = callback;     = data;     = undefined;} return IO ({    | | ' Get ',    url:url,    data:data,    complete:callback,    datatype:datatype});}

the expected invocation of Io,datatype is set to the Jsonp,get request. Other parameters are consistent with the general AJAX parameters, datatype obvious clues. Specially in getScript:require.load left a heart, because Getscript is responsible for script send work, and jsonp it itself is a kind of getscript.
var IO = require ('./base '); then take a look at the Base.js .
Summary: The Io.js function is to load each JS file, then add a few convenient entry to IO, finally unified call IO function.


Base.js
first of all we will certainly be defaultconfig attracted attention, because here set up the various default Ajax required configuration, HTTP request Mothods, MIME type, encoding, etc., the general Converter settings are also in this object.
Next is the function that sets the configuration Setupconfig (c), before we do not know what parameters will be passed or not read (actually see also can, see Code also can guess a sorta).
then directly find the IO function, the parameter is C. Self is an example of an IO function. Then to the IO sleeve on the Promise mode, you can use the chain operation to come ~ (I also see Yiminghe chicory notes Music!). ' 2012-2-07 [email protected] -return Promise type Object, you can chain-action! ' Lying trough .... So cute! )。 Self.userconfig = C;c = Setupconfig (c); Our parameters are now passed to Setconfig and a new parameter object is generated. In order not to interrupt the analysis of the IO function. Let's go back to the analysis. Util.mix is to clone the following object to self, and then adds a bunch of properties such as Config,transport,timeouttimer. Next, declare the transporter constructor, the transporter variable, and then trigger the start event! This marks the beginning of Io! The following is followed by selecting the corresponding transporter according to the datatype and creating the instance. Then there is the Ajax-related header, readyState, status, and so on, which has nothing to do with JSONP. Then it mimics the timeout function with settimeout. There's nothing left to come. At the end of the base.js, we added the methods like Setupconfig,setuptransport,gettransport to the IO function to implement the Config setting and other functions. And what we care about is the Setuptransport, transmitter settings.
Now we look back at setupconfig. Its return value is a new Config object.
in the beginning with the parameter C depth clone to Defaultconfig, after combining to produce the desired config assignment to C, like this

     var context = c.context;      Delete C.context;      = Util.mix (Util.clone (Defaultconfig), C, {     true     });      = Context | | C

The context represents the "environment" (Context fool Translator)--success,error,complete of the callback function after the request. After declaring a variable or something, Uri = C.uri, is a URL object that contains all the relevant parameters of the URL. Uri.query is a JSON-formatted object/array consisting of the name/value pairs querystring in the URL. We exclude the cross-domain unrelated processing process, JSONP most of them are not AH ~

DataType = C.datatype = Util.trim (DataType | | ' * '). Split (Rspace); if  in C) && Util.inarray (datatype[0], [' Script ', ' Jsonp 'false;}

Util.trim remove datatype before and after the space, Rspace =/\s+/,split separated by a space datatype into a substring array. Then confirm that datatype is JSONP. The C.cache identifies whether the script or the JSONP transmitter is called, and false means yes. It works: URLs are added uri.query._ksts = Util.now () + ' _ ' + util.guid (); That is, the ksts= timestamp _ global Unique identifier, the function of the GUID function is to generate a global unique identifier, English is generally called UUID or GUID.
Here, the URL processing is complete. Now is still an object.
and then it start!. There are many event handlers for the start event, and they will be judged before execution, and we'll start the Jsonp.js section with datatype[' Jsonp ' in hand.


Jsonp.js
The first thing to note is that
io.setupconfig ({    ' callback ',    function  () {    //  Do not use Now (), in extreme cases may repeat    return util.guid (' Jsonp ');    }});
Setupconfig is called, apparently the function parameter name is initialized to callback. Jsonpcallback is a function that initializes a globally unique identifier. The following util.guid is a global unique identifier, added after ' Jsonp ' as the function name, and globally unique to prevent the name of this function and other variable names. The function name string is first generated in the callback function of the start event after, and then included in uri.query c.uri.query[c.jsonp] = jsonpcallback;. The function then executes a series of programs that are common to jsonp. Create a global function, bind the Global object win[Jsonpcallback], and set the delete win[Jsonpcallback] After the request is complete;. The note here is to bind to the global object , because the global variables declared by the direct Var cannot be cleared. And Kissy used a little trick here, which creates a temporary global function that gives a variable called previous, and then win[jsonpcallback] = Previous when the callback function is completed at the end of the request. If loaded successfully, the previous will be executed to save the required JSON format data. After that, the converter converters.script.json is defined. where return response[0], the returned value has been saved before response = [R],[r] is the parameter of the global function, the converter has done so! The failure also has a relative handling mechanism for the throw new Error (' Not a call Jsonpcallback: ' + jsonpcallback); Finally, the DataType is modified to datatype[0] = ' script '; DATATYPE[1] = ' json '; The combination of annotations makes it easy to know that you are preparing to call the script sender. Summary: jsonp.js defines, adds a URL in the global function parameter name/value, global function definition, call, delete, script to the JSON converter to implement this series of behaviors, and bind to the start event.
we go back to base.js and the following is ready to send.
transportconstructor = transports[c.datatype[0]] | | transports[' * '];
transport = new transportconstructor (self);as already known in Jsonp.js, the script transporter is responsible for sending the request. In fact, JSONP and getscript the principle of sending the request is the same, dynamic loading JS script, so the final uniform use of the script transmitter is not surprising. and Io.setuptransport work as early as io.js loading *-transport.js time has been completed, like this io.setuptransport (' script ', scripttransport); So Io.setuptransport (' iframe ', iframetransport); (Don't ask me how I know, to the transmitter section, of course I will open to see ~). Look at Setuptransport.
DataType = C.datatype = Util.trim (DataType | | ' * '). Split (Rspace); if  in C) && Util.inarray (datatype[0], [' Script ', ' Jsonp 'false;}

After all, it 's obviously open script-transport.js .  Script-transport.jsOpen the first sight is still initialized. Then it is to determine whether the browser supports XHR2 CORS, and then replace the transmitter, Ajax request. This time we do not talk about, the Ajax module is somewhat complex, the detailed interpretation of the words are too long. Then the traditional script is sent, adding the Send,_callback,abort method to the script sender. The Send definition io.script is require.load (usage can refer to jquery.load) and the URL is Io._geturlforsend (). Base.js mentioned this method in Methods.js in the comments. We'll go and see it later. After that, there are encoding settings and callback parameters for various states. _callback removes the Io.script, prevents repeated calls, and then passes the corresponding parameters to the Io._ioready based on the state. Abort, as the name implies, interrupts the function. Summary: The send and callback of the script sender is defined in Script-transport.js.  go back to see Methods.js Methods.jsthe start is to process the response data function Handleresponsedata. Jsonp to be aware of these
    varPrevtype = datatype[0];  for(vari = 1; i < datatype.length; i++) {type=Datatype[i]; varconverter = Converts[prevtype] &&Converts[prevtype][type]; if(!Converter) {            Throw NewError (' No covert for ' + prevtype + ' = + ' +type); } responsedata=Converter (responsedata); Prevtype=type; } io.responsedata= ResponseData;

Jsonp.js last set datatype[0] = ' script '; datatype[1] = ' json '; Here the converter designates Converters.script.json, then executes the JSON data that will be received to io.responsedata. By this point, JSONP's data processing was completely completed. is not associated with script. The translator for script has also been implemented in Jsonp.js. Util.extend implements IO Inheritance promise objects, and adds some methods to the prototype. Most of the processing of the header, and we are only concerned about _ioready, _geturlforsend. The callback function _ioready the response from the incoming status Code and state text (Success,error), and succeeds in calling Handleresponsedata, which fails to be thrown. There is a settimeout, because throw e will not allow the subsequent code to continue, so you need to solve this problem asynchronously. the implementation of Ajax timeout is the same! ). _geturlforsend is to convert the URL object to a URL string! The URL appears here! (Kissy Apidoc not url.stringify, in fact url.stringify = Url.format, do not doubt! I specially read the util source! )。 Summary: Methods.js is responsible for handling response data and URL generation.  Finally, back to Base.js .Yiminghe Chicory in the back of the self-supporting flag (//flag as sendingf! l! a! g! See immediately laugh)! Then Ransport.send ()! The following error handling has been mentioned before, and _ioready the same question. End. The following is a simple example of the Kissy IO module, which implements the call to the Flickr API (both at home and abroad like this test)   
<script>          (function() {               varApiurl = ' Http://api.flickr.com/services/feeds/photos_public.gne '; varOnsuccess =function(data) {Console.log (' Get data: ', data); } require ([' io '),function(IO) {io ({url:apiurl, type:' GET ', DataType:' Jsonp ', Jsonp:' Jsoncallback ', Jsonpcallback:' CTest ', data: {Tags:"Water", Tagmode:"Any", Format:"JSON"}, complete:onsuccess});          }); })()     </script>
View Code

then is the program to achieve the whole process, let us review the previous content, comb the idea.   Analysis Summary Advantages : Chinese English and Chinese combine to make the readability of annotations greatly enhanced! The code structure is very clear, front and back reading is very smooth, basically no obstacles. In the implementation of JSONP there is a priority to try Cors, callback function processing for me is also a small highlight. COMMONJS Specification module loading is different, also let the module development become very indirect embodiment of Ali front-end chicory to Nodejs's strong admiration. cons : Similar to Util.parsejson, url.stringify these are not mentioned in the API documentation, resulting in the need to go to other modules to view the source code, increased analysis time-consuming. That's a disadvantage! I hope the kissy chicory can improve some documents. Then there is the love of English comments ~ Although very fun ~ but this also gave me the way to give chicory advice! (I found the obvious word error, have feedback) 

The last of the broken thoughts

the depth of this analysis is certainly not enough, because Wu bei is a JS entry born. So I hope you find what write wrong, must tell me ah! It would be nice if chicory passed a little advice. Also hope that my blog can give you want to read the framework of the source but also slow to move forward students, a little thought and confidence (I can see this dish!) Also dare to send blog! )。 Finally, some students guessed right, this will be a series of text!

Analysis of how JS Framework realizes the Kissy of Jsonp

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.