1. 程式人生 > >jquery原始碼對jsonp的解讀

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); 無需傳遞引數