jquery.getJSON跨域方案实现原理

jquery.getJSON在实现与后台程序异步交互方面非常的方便,在不牵扯跨域的情况下,实现也很简单。

使用方法为:

$.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('你错了');}
});

后台处理程序:
 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参数连同数据一起返回给前端。
 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 omittedif ( 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 requestsif ( s.crossDomain ) {var script,head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;return {send: function( _, callback ) {script = document.createElement( "script" );
		script.async = "async";if ( s.scriptCharset ) {script.charset = s.scriptCharset;}script.src = s.url;// Attach handlers for all browsersscript.onload = script.onreadystatechange = function( _, isAbort ) {if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {// Handle memory leak in IEscript.onload = script.onreadystatechange = null;// Remove the scriptif ( head && script.parentNode ) {head.removeChild( script );}// Dereference the scriptscript = undefined;// Callback if not abortif ( !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的

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部