jquery.getJSON跨域方案實現原理
阿新 • • 發佈:2019-01-25
jquery.getJSON在實現與後臺程式非同步互動方面非常的方便,在不牽扯跨域的情況下,實現也很簡單。
使用方法為:
後臺處理程式:
相比較而言,對於跨域的getJSON實現略顯複雜:來看jquery是如何實現的,比如我前端頁面傳送一個請求
發現這種請求比同域的請求,url地址多了一項引數——jsoncallback,此引數名自定義。而後臺程式在處理的時候會把此jsoncallback引數連同資料一起返回給前端。
getJSON: function( url, data, callback ) {
return jQuery.get( url, data, callback, "json" );
},
ok,重點關注引數callback向後溯源get方法:
發現是走的ajax方法: 其實getJSON方法等同於dataType為'json'的ajax方法,再向下探究ajax方法:
跨域檢查有一個例外那就是HTML的<Script>標記;我們可以<Script>的src屬性,來訪問獨立域名下或者其它站點的js資源。這個url響應的結果可以有很多種,比如JSON,返回的Json值成為<Script>標籤的src屬性值,這就是運用了jsonp的方法載入一個js。
使用方法為:
$.getJSON('http://***.**/test/test.php', {'uid':1235,'cid':5678}, function(data){
if(data.success == 1){
alert(data.message+'\n'+data.success+'\n'+data.uid);
}else{
alert('你錯了');
}
});
後臺處理程式:
<?php $cid = $_GET['cid']; $uid = $_GET['uid']; $response['cid'] = $cid; $response['uid'] = $uid; if($uid > 1234){ $response['success'] = 1; }else{ $response['success'] = 0; } $response['message'] = '您的請求成功'; echo json_encode($response);
相比較而言,對於跨域的getJSON實現略顯複雜:來看jquery是如何實現的,比如我前端頁面傳送一個請求
$.getJSON( 'http://***.**/test/test.php?jsoncallback=?', {'uid':1235,'cid':5678}, function(data){ if(data.success == 1){ alert(data.message+'\n'+data.success+'\n'+data.uid); }else{ alert('你錯了'); } } );
發現這種請求比同域的請求,url地址多了一項引數——jsoncallback,此引數名自定義。而後臺程式在處理的時候會把此jsoncallback引數連同資料一起返回給前端。
<?php $callback = $_GET['jsoncallback']; $cid = $_GET['cid']; $uid = $_GET['uid']; $response['cid'] = $cid; $response['uid'] = $uid; if($uid > 1234){ $response['success'] = 1; }else{ $response['success'] = 0; } $response['message'] = '您的請求成功'; echo $callback . '(' . json_encode($response) .')';
此jsoncallback作為資料一起返回給了前端,它在跨域方面起什麼作用呢? 通過檢視firebug的響應資料可以發現,他是jquery自動生成的函式名稱。
接下來,我們來一起看jquery.getJSON程式碼原理。 一步步跟進來看,首先找到getJSON方法:getJSON: function( url, data, callback ) {
return jQuery.get( url, data, callback, "json" );
},
ok,重點關注引數callback向後溯源get方法:
jQuery.each( [ "get", "post" ], function( i, method ) {
jQuery[ method ] = function( url, data, callback, type ) {
// shift arguments if data argument was omitted
if ( jQuery.isFunction( data ) ) {
type = type || callback;
callback = data;
data = undefined;
}
return jQuery.ajax({
type: method,
url: url,
data: data,
success: callback,
dataType: type
});
};
});
發現是走的ajax方法: 其實getJSON方法等同於dataType為'json'的ajax方法,再向下探究ajax方法:
// Bind script tag hack transport
jQuery.ajaxTransport( "script", function(s) {
// This transport only deals with cross domain requests
if ( s.crossDomain ) {
var script,
head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
return {
send: function( _, callback ) {
script = document.createElement( "script" );
<span style="white-space:pre"> </span>script.async = "async";
if ( s.scriptCharset ) {
script.charset = s.scriptCharset;
}
script.src = s.url;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function( _, isAbort ) {
if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
// Remove the script
if ( head && script.parentNode ) {
head.removeChild( script );
}
// Dereference the script
script = undefined;
// Callback if not abort
if ( !isAbort ) {
callback( 200, "success" );
}
}
};
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore( script, head.firstChild );
},
跨域檢查有一個例外那就是HTML的<Script>標記;我們可以<Script>的src屬性,來訪問獨立域名下或者其它站點的js資源。這個url響應的結果可以有很多種,比如JSON,返回的Json值成為<Script>標籤的src屬性值,這就是運用了jsonp的方法載入一個js。