jquery源码对jsonp的解读


/**
 * 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 settings
1.
首先在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
    }).

    < script
async = ""
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)"; //jsonp
console.log('jsonp: '+str);
res.end(str);
无需传递参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值