這篇文章主要介紹了JavaScript中模擬實現jsonp,本文直接給出實現代碼,代碼中包含詳細注釋,需要的朋友可以參考下
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 function prescript(s) { if (s.cache === undefined) { s.cache = false; } if (s.crossDomain) { s.type = "GET"; } } function prejsonp(s, originalSettings, jqXHR) { // 給回調函數命名 var callbackName = s.jsonpCallback s.url += (/(?:)/.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName; // 腳本執行後使用數據轉換器來檢索json // 提供給代碼獲取服務器的是據 s.getData = function() { if (!responseContainer) { jQuery.error(callbackName + " was not called"); } return responseContainer[0]; }; //修改處理機制 s.dataTypes[0] = "json"; // 創建一個全局函數 overwritten = window[callbackName]; //用來收集服務器給的數據 window[callbackName] = function() { responseContainer = arguments; }; return "script"; } /** * jsonp的預先處理 */ function inspectPrefiltersOrTransportsA(options, originalOptions, jqXHR) { //預處理jsonp var dataTypeOrTransport = prejsonp(options, originalOptions, jqXHR) //擴充dataTypes options.dataTypes.unshift(dataTypeOrTransport); //預處理script類型 prescript(options) } /** * 分發器 * @return {[type]} [description] */ function inspectPrefiltersOrTransportsB(s, originalOptions, jqXHR) { return { send: function(_, complete) { var script = jQuery("<script>").prop({ async: true, charset: s.scriptCharset, src: s.url }).on( "load error", callback = function(evt) { script.remove(); callback = null; if (evt) { complete() } } ); //<script async="" src="http://192.168.1.113:8080/github/jQuery/jsonp.php document.head.appendChild(script[0]); } } } /** * 模擬ajax的 jsonp請求 * @param {[type]} options [description] * @return {[type]} [description] */ function createAjax(options) { if (typeof url === "object") { options = url; url = undefined; } options = options || {}; /** * 參數 * jQuery.ajaxSetup 是默認參數 * @type {[type]} */ var s = jQuery.ajaxSetup({}, options); // Deferreds // 異步機制 var deferred = jQuery.Deferred(); var completeDeferred = jQuery.Callbacks("once memory"); /** * 實際返回的ajax對象 * @type {Object} */ var jqXHR = {} // 把jqXHR對象轉化promise對象,幷加入complete、success、error方法 deferred.promise(jqXHR).complete = completeDeferred.add; //別名 jqXHR.success = jqXHR.done; jqXHR.error = jqXHR.fail; s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(/(?:)/) || [""]; //預處理 inspectPrefiltersOrTransportsA(s, options, jqXHR); for (i in { success: 1, error: 1, complete: 1 }) { jqXHR[i](s[i]); } /** * 分發器 */ transport = inspectPrefiltersOrTransportsB(s, options, jqXHR); function done(status, nativeStatusText, responses, headers) { console.log(s,s.getData()) } //發送請求 transport.send(s, done); return jqXHR; } function show(data){ $('body').append('<li>'+ data +'</li>'); } /** * 數據回調接收 * @return {[type]} [description] */ function flightHandler(){ } $("#test").click(function(){ //執行一個異步的HTTP(Ajax)的請求。 var ajax = createAjax({ url: 'http://192.168.1.113:8080/github/jQuery/jsonp.php', data: { 'action': 'aaron' }, // 預傳參的數組 dataType: 'jsonp', // 數據類型 jsonp: 'callback', // 指定回調函數名,與服務器端接收的一致,並回傳回來 jsonpCallback:flightHandler, success: function() { show('局部事件success') } }) })