您现在的位置是:首页 > 技术学习 > javascript 网站首页 技术学习 javascript

JS、Jquery中jsonp的原理以及使用方法

简介 sonp实现跨域请求数据的原理:jsonp允许服务器在后台生成一段js代码(回调函数),将数据写进回调函数里,然后返回给页面,页面接收回调函数后在页面执行,可获取到数据。

我们平常使用ajax从前端发起请求获取数据,一般请求的地址都是和当前网页是同源的,即不能进行跨域请求,(跨域:主域名、子域名、端口号其中有一个不同就属于跨域);

Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。

虽然普通ajax不能跨域,但是script标签是可以跨域引用的,即JS可以跨域使用。因此:

jsonp实现跨域请求数据的原理:jsonp允许服务器在后台生成一段js代码(回调函数),将数据写进回调函数里,然后返回给页面,页面接收回调函数后在页面执行,可获取到数据。注:因此,jsonp返回给页面的不是数据本身,而是回调函数,数据可从回调函数中获取。
举例:

1. jquery写法:

第一种写法:ajax

<script type="text/javascript">
    // 前端通过jquery发起ajax请求
    $.ajax({
        type : "GET", // 获取方式,好像jsonp不支持post...
        url : "http://127.0.0.1/jsonp/jsonp.php", // 请求的地址
        async:false, // 同步
        dataType : "jsonp", // 数据类型,必须是jsonp,这样才能进行跨域操作
        data : "", // 传给后台的数据,可省略。
        jsonp : "callback", 
        // 用于指定回调函数,可为任意名字,但是必须和后台用GET获取用的名字保持一致。
        jsonpCallback : "myCallBack", 
        // 自定义回调函数名,可省略,默认jq会自动随机生成函数名传给后台。
        success : function (data) { // 请求成功时执行的函数,其中data就是后台数据。
            console.log(data); 
        },
        error : function (e) {
            console.log("e");
        }
    });
</script>

第二种写法: get请求

<script type="text/javascript">
    $.getJSON('http://127.0.0.1/jsonp/jsonp.php?callback=?',function (data) {
        console.log(data);
    }); 
    // ?后面的callback=?用来标识是jsonp请求。其中callback必须和后台get获取数据时用的名字一样。
</script>

2.原生JS实现jsonp

function jsonp(options) {
    // 请求参数设置
    options = options || {};
    // 创建js标签用于执行jsonp
    var oHead = document.getElementsByTagName('head')[0];
    var oScript = document.createElement('script');
    // 给window绑定和callback参数值相同的函数,用于获数据
    var _callback = options.callback;
    window[_callback] = function (data) {
        // 形参data 用于接收后台返回的 callback函数 的实参(数据)
        // 获取数据成功后清除jsonp的js
        oHead.removeChild(oScript);
        // 清除加载超时的定时函数(加载成功,超时函数不用执行了)
        clearTimeout(oScript.timer);
        // 清除回调函数
        window[_callback] = null;
        // 执行请求成功的回调函数,把callback里的参数再传给succeed函数。succeed 函数里面执行对数据的操作
        options.success && options.success(data);
    }
    // js发起请求,请求成功后返回的代码是让 callback 执行的,而且实参就是后台数据
    var url = options.url.indexOf('?') > -1 ? options.url + '&callback=' + options.callback : options.url + '?callback=' + options.callback;
    if(options.data) {
        for(var k in options.data) {
            url += '&' + k + '=' + options.data[k];
        }
    }
    oScript.src = url;
    oHead.appendChild(oScript);
    // 超时函数,请求超时走error逻辑
    if (options.timeout) {
        oScript.timer = setTimeout(function() {
            // 错误后清除回调函数
            window[_callback] = null;
            oHead.removeChild(oScript);
            // 执行error函数
            options.error && options.error({ message: "超时" });
        }, options.timeout * 1000);
    }
};

// 测试执行
var params = {
    url: 'http://127.0.0.1/jsonp/jsonp.php',
    callback: 'getback',
    timeout: 10,
    data: {
        param1: 'a',
        param2: 2
    },
    success: function(data) {
        console.log(data);
    },
    error: function(e) {
        console.log(e);
    }    
}; // 其他参数配置可根据需求添加
jsonp(params);

3. 后台文件jsonp.php写法

<?php
    // 要返回的数据
    $data = '{
        "shuju1" : "1",
        "shuju2" : "2",
        "shuju3" : "3",
        "shuju4" : "4",
        "shuju5" : "5"
    }';

    // 获取请求传过来的值,用于定义要返回的回调函数名,
    $callback = $_GET['callback']; 
    // 中括号里的'callback',必须和前端ajax里的的jsonp:"callback",中jsonp的值名字一样

    // 将回调函数名和数据拼接成函数的形式。数据以入参的形式传入。
    echo $callback . "(" . $data . ")";
?>

个人CSDN

Top