jquery源码对jsonp的解读

来源:互联网 发布:linux 删除逻辑卷 编辑:程序博客网 时间:2024/06/08 03:38


/** * Created by ANN on 2017/6/8. */基本语法$.ajax({    url: "http://localhost:18080/get",    type: "get",    dataType: 'jsonp',    jsonpCallback: "baiducallback"}).done(function (data) {    console.log(data)})首先要了解ajaxSetip方法ajax方法会将两个参数进行覆盖,拷贝,最后返回ajaxSetup: function( target, settings ) {    return settings ?        // Building a settings object        ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :        // Extending ajaxSettings        ajaxExtend( jQuery.ajaxSettings, target );},function ajaxExtend( target, src ) {    var key, deep,        flatOptions = jQuery.ajaxSettings.flatOptions || {};    for ( key in src ) {        if ( src[ key ] !== undefined ) {            ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];        }    }    if ( deep ) {        jQuery.extend( true, target, deep );    }    return target;}jsonCallback分两种情况一.不穿参数:$.ajax({    url: "http://localhost:18080/get",    type: "get",    dataType: 'jsonp',}).done(function (data) {    console.log(data)})// Default jsonp settings1.首先在jquery内部执行进入ajax内部执行s = jQuery.ajaxSetup( {}, options ),jQuery.ajaxSetup({    jsonp: "callback",    jsonpCallback: function () {        var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );        this[callback] = true;        return callback;    }此时setting不存在执行 ajaxExtend( jQuery.ajaxSettings, target );    ajaxSettings    在jquery初始会有定义ajaxSettings: {        url: ajaxLocation,        type: "GET",        isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),        global: true,        processData: true,        async: true,        contentType: "application/x-www-form-urlencoded; charset=UTF-8",    },    此时target是我们传递的参数    {        url: "http://localhost:18080/get",        type: "get",        dataType: 'jsonp',    }此时url会被覆盖,平增加dataType参数ajaxSettings此时是:ajaxSettings: {    url: ajaxLocation,        type: "GET",        isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),        global: true,        processData: true,        async: true,        contentType: "application/x-www-form-urlencoded; charset=UTF-8",        dataType: 'jsonp',        jsonpCallback: function () {        var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );        this[callback] = true;        return callback;    }},jquery的ajaxSetup方法会使用自定义的jsonpCallback,返回如callback = jQuery21402091185757493652_1496931076460 & _ = 1496931076461其中对应方法是jQuery21402091185757493652_1496931076460 =》jqueryexpando: "jQuery" + ( version + Math.random() ).replace(/\D/g, "")产生1496931076461 =》var nonce = jQuery.now();2.对上面方法进行调用callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback)s.jsonpCallback():s.jsonpCallback;3.定义该方法overwritten = window[callbackName];window[callbackName] = function () {    responseContainer = arguments;};4.动态产生一个script标签并引用该链接script = jQuery("<script>").prop({        async: true,        charset: s.scriptCharset,        src: s.url    }).    < scriptasync = ""src = "http://localhost:18080/get?callback=jQuery21405753958643171866_1496932371372&amp;_=1496932371373" > < / script >向后发送的url: "http://localhost:18080/get?callback=jQuery21405753958643171866_1496932371372&amp;_=1496932371373"    5.请求完成后通过上述方法删除script节点(elem.parentNode){    if (keepData && jQuery.contains(elem.ownerDocument, elem)) {        setGlobalEval(getAll(elem, "script"));    }    elem.parentNode.removeChild(elem);}二.传参$.ajax({    url:"http://localhost:18080/get",    type:"get",    dataType:'jsonp',    jsonpCallback:"baiducallback"}).done(function (data) {    console.log(data)})s = jQuery.ajaxSetup( {}, options ),如第一种情况执行之后:    ajaxSettings: {    url: ajaxLocation,        type: "GET",        isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),        global: true,        processData: true,        async: true,        contentType: "application/x-www-form-urlencoded; charset=UTF-8",        dataType: 'jsonp',        jsonpCallback: "baiducallback"    }},向后台发送的url:"http://localhost:18080/get?callback=baiducallback&_=1496934184545"总结:传参与否看业务的需要传参的大部分情况是后台没有处理能力,只是单纯的请求一个json文件例如baiducallback({data:..})而后台可以处理参数var str = req.query.callback + "(" + JSON.stringify(data)"; //jsonpconsole.log('jsonp: '+str);res.end(str);无需传递参数