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

后台处理程序:
<?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。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值