search

Home  >  Q&A  >  body text

为啥跨域要用jsonp,jsonp是不是一种协议,和json什么关系?

js跨域请求不同域名下的数据,如果是放在script标签中,直接用src属性就可以了,为什么还要用jsonp跨域。这种跨域请求主要有哪些作用?

高洛峰高洛峰2940 days ago846

reply all(4)I'll reply

  • 欧阳克

    欧阳克2016-11-10 10:35:25

    都传送,我来简单说一下原理吧

    论据:

    jsonp和ajax没半毛钱关系

    jsonp和json也没半毛钱关系

    证明:

    script:src 是不会跨域的,这是主要论据

    这个1.js的内容为:

    var RESULT = {"data": .....};

    这样加载之后,大家都可以获得RESULT这个变量,这个很容易理解。

    那jQuery的ajax是如何请求并加载这个页面呢?

    $.getScript('http://.../1.js', function(){
        console.log(RESULT.data);
    });
    或
    $.ajax({
        url: 'http://.../1.js',
        dataType: 'script',
        success: function(){
            console.log(RESULT.data);
        }
    }

    看起来是用ajax请求的,其实是jQuery做了一个模拟,真实代码更像:

    var s = document.createElement('script');
    s.src = 'http://.../1.js';
    s.onload = function(){
        通知jQuery.ajax,我已经加载完毕了
    }

    为什么会诞生jsonp?

    因为在当年,IE 6风行的时候,getScript(或ajax{dataType:'script'},下同),请求jpg/js/css资源是同步的,也就是请求到一个之后,才会请求下一个,而当年网络上的ajax控件也大部分是做的同步。

    为了异步请求,Chrome诞生了。

    但是异步会到导致一个问题:因为网络的原因,我根本不知道RESULT变量是谁传回来的,并且RESULT会被后请求到的数据覆盖。

    所以聪明的前端工程师想到

    calljQueryWhoAmI({"data": ....});

    这个calljQueryWhoAmI是不停变化的

    jsonp流程用户发起jsonp请求

    $.ajax({
        url:'http://.../1.php?callback=?',
        dataType: 'jsonp',
    });

    jquery开始做如下工作

    //生成一个callback的随机名字
    var callback = 'callback_123456789';
    //替换用户的网址为 
    http://.../1.php?callback=callback_123456789
    //新建一个函数来接受数据
    var callback_123456789 = function(json) {
        call success(json)
    }
    //开始使用```createElement('script').src="http://.../1.php?callback=callback_12345789"```请求

    用户收到http://.../1.php?callback=callback_123456789做的工作

    也就是得到了

    callback_12345789({"data": ...})

    当这个加载完毕时,系统会自动去

    call callback_12345789

    流程继续到jQuery的

    var callback_123456789 = function(json)

    你接受到数据,开始工作


    reply
    0
  • 三叔

    三叔2016-11-10 10:30:52

    如果你请求出去,然后需要处理请求返回的结果,这个时候jsonp的用处就出来了,一个回调函数,里面有你需要处理的数据。

    reply
    0
  • 欧阳克

    欧阳克2016-11-10 10:30:42

    这篇文章讲的挺好的其实:看完就大概懂了,在这里推荐下。                   

    http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html


    reply
    0
  • 三叔

    三叔2016-11-10 10:30:27

    因为根据浏览器同源策略,a 域的js不能直接访问 b域名的信息,但是script 标签的src属性可以跨域引用文件,jsonp是请求之后后台包装好一段json,并且把数据放在一个callback函数,返回一个js文件,动态引入这个文件,下载完成js之后,会去调用这个callback,通过这样访问数据。

    reply
    0
  • Cancelreply