zoukankan      html  css  js  c++  java
  • jsonp的实现原理和缺点

    之前只了解到jsonp是动态加载js,利用src的实现跨域

    今天查资料总结以下

    一、实现原理

    jsonp的原理本质就是利用script标签的src的天然可跨域特性实现跨域,让服务器接收浏览器传过来的函数名,返回一个带参的函数调用,浏览器接收数据,完成函数调用

    JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

    <script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行。

    JSONP的实现模式--CallBack

    如何实现JSONP的javascript callback的形式。

    程序A中sample的部分代码:

    <script type="text/javascript">
    //回调函数
    function callback(data) {
        alert(data.message);
    }
    </script>
    <script type="text/javascript" src="http://localhost:20002/test.js"></script>
    

    程序B中test.js的代码:

    //调用callback函数,并以json数据形式作为阐述传递,完成回调
    
    callback({message:"success"});
    

    这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

    将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义吧。

    一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

    程序A中sample的部分代码:

    <script type="text/javascript">
       function callback(data) {
           alert(data.message);
       }
       //添加<script>标签的方法
       function addScriptTag(src){
       var script = document.createElement('script');
           script.setAttribute("type","text/javascript");
           script.src = src;
           document.body.appendChild(script);
       }
       
       window.onload = function(){
           addScriptTag("http://localhost:20002/test.js");
       }
    </script>
    

    程序B的test.js代码不变,我们再执行下程序,是不是和原来的一样呢。

    如果我们再想调用一个远程服务的话,只要添加addScriptTag方法,传入远程服务的src值就可以了。

    这里说明下为什么要将addScriptTag方法放入到window.onload的方法里,原因是addScriptTag方法中有句document.body.appendChild(script);,这个script标签是被添加到body里的,由于我们写的javascript代码是在head标签中,document.body还没有初始化完毕呢,所以我们要通过window.onload方法先初始化页面,这样才不会出错。

    上面的例子是最简单的JSONP的实现模型,不过它还算不上一个真正的JSONP服务。

    我们来看一下真正的JSONP服务是怎么样的,比如Google的ajax搜索接口:http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=?&callback=?

    q=?这个问号是表示你要搜索的内容,最重要的是第二个callback=?这个是正如其名表示回调函数的名称,也就是将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调。有点罗嗦了,还是看看实现代码吧:

    <script type="text/javascript">
       //添加<script>标签的方法
       function addScriptTag(src){
           var script = document.createElement('script');
           script.setAttribute("type","text/javascript");
           script.src = src;
           document.body.appendChild(script);
       }
       
       window.onload = function(){
           //搜索apple,将自定义的回调函数名result传入callback参数中
           addScriptTag("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=apple&callback=result");
           
       }
       //自定义的回调函数result
       function result(data) {
           //我们就简单的获取apple搜索结果的第一条记录中url数据
           alert(data.responseData.results[0].unescapedUrl);
       }
    </script>

    jQuery对JSONP的实现

    jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法(详细可以参考JQ实现jsonp)。

    那我们就来修改下程序A的代码,改用jQuery的getJSON方法来实现(下面的例子没用用到向服务传参,所以只写了getJSON(url,[callback])):

    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
        $.getJSON("http://localhost:20002/MyService.ashx?callback=?",function(data){
            alert(data.name + " is a a" + data.sex);
        });
    </script>
    

    结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。这个函数名大家可以debug一下看看,比如jQuery17207481773362960666_1332575486681。

      当然,加入说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现(参数较多,详细可以参考http://api.jquery.com/jQuery.ajax)。先来看看如何实现吧:
      

    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
    <script type="text/javascript">
       $.ajax({
            url:"http://localhost:20002/MyService.ashx?callback=?",   
            dataType:"jsonp",
            jsonpCallback:"person",
            success:function(data){
                alert(data.name + " is a a" + data.sex);
            }
       });
    </script>
    

    没错,jsonpCallback就是可以指定我们自己的回调方法名person,远程服务接受callback参数的值就不再是自动生成的回调名,而是person。dataType是指定按照JSOPN方式访问远程服务。

      利用jQuery可以很方便的实现JSONP来进行跨域访问。先暂时写到这吧。

     

    二、缺点

    1.需要服务器后台的支持
    2.只能发生get请求
    3.数据传输相对不安全

  • 相关阅读:
    Leetcode Unique Binary Search Trees
    Leetcode Decode Ways
    Leetcode Range Sum Query 2D
    Leetcode Range Sum Query
    Leetcode Swap Nodes in Pairs
    Leetcode Rotate Image
    Leetcode Game of Life
    Leetcode Set Matrix Zeroes
    Leetcode Linked List Cycle II
    CF1321A
  • 原文地址:https://www.cnblogs.com/zhilu/p/13808833.html
Copyright © 2011-2022 走看看