JSONP的使用及原理

1、JSONP的诞生过程综述 1) Ajax无法跨域,引起了开发者的思考。 2) 开发者发现, <script>标签的src属性是可以跨域的,是否可以把跨域服务器写成调用本地的函数,回调数据回来?...

1、JSONP的诞生过程综述


1) Ajax无法跨域,引起了开发者的思考。


2) 开发者发现, <script>标签的src属性是可以跨域的,是否可以把跨域服务器写成调用本地的函数,回调数据回来?


3) JavaScript刚好支持JSON(object)。


4) 调用跨域服务器上动态生成的js格式文件(不管是什么样的跨域服务器,最终生成的返回值都是一段js代码)。


5) 这种获取远程数据的方式看起来非常像Ajax,但其实并不一样,逐渐形成了一种非正式传输协议,称作JSONP。


6) 传递一个callback参数给跨域服务器,然后跨域服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据进而返回。





2、JSONP的诞生过程细述


1) 哪怕跨域js文件中的代码,web页面也是可以无条件执行的。 


远程服务器www.server.com根目录下的server.js文件: 


alert(“我是跨域调用得到的响应”);

本地服务器www.client.com根目录下的client.html文件:


<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="http://www.server.com/server.js"></script>
</head>
<body>
</body>
</html>

跨域调用显然可以成功。


问题:跨域远程获取数据如何实现?


 


2) 在client.html页面定义一个函数,然后在server.js中传入数据进行调用。


远程服务器www.server.com根目录下的server.js文件: 


serverResponse({"result":"我是跨域调用得到的响应"});

本地服务器www.client.com根目录下的client.html文件:


<!DOCTYPE html>
<html >
<head>
    <title></title>
    <script>
    var serverResponse = function(data){
        alert(“跨域调用得到的响应是:” + data.result);
    };
    </script>
    <script src="http://www.server.com/server.js"></script>
</head>
<body>
</body>
</html>

跨域远程获取数据的目的实现。


问题:JSONP的服务器往往要面对很多客户端,而这些客户端各自的本地函数都不相同,如何让服务器知道它应该调用的本地函数是什么?


 


3) 服务器提供的JS脚本动态生成,客户端传递一个参数告诉服务器要查询的信息,服务器根据客户端的需求来动态生成JS脚本。


远程服务器www.server.com根目录下的getResult.jsp文件动态生成的JS脚本:


serverResponse({
"name":"Amy",
"age":23,
"school":"BUPT"
});

本地服务器www.client.com根目录下的client.html文件:


<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script>
    var serverResponse = function(data){
        alert("跨域调用得到的响应是:" + data.result);
    };
    var url = "http://www.server.com/getResult.jsp?name=Amy&callback=serverResponse";
var script = document.createElement('script');
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);
    </script>
</head>
<body>
</body>
</html>

问题:如何实现多次和重复调用?jQuery如何实现JSONP调用? 




3、JSONP的基本原理


JSONP的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。其实,JSONP跨域方式与Ajax XmlHttpRequest协议无关。




4、JSONP的执行过程:


1) 客户端注册一个callback (如:'jsoncallback'), 然后把callback的值(如'jsonpValue')传给服务器;


2) 服务端得到callback的数值后,要用jsonpValue(......)把将要输出的JSON内容包括起来,此时,服务器生成JSON数据才能被客户端正确接收。


3) 以JavaScript语法的方式,生成一个function,function 名字是传递上来的参数 'jsoncallback'的值'jsonpValue'.


4) 最后将JSON数据直接以参数的方式,放置到function中,生成了一段js格式文件,返回给客户端。


5) 客户端浏览器,解析script标签,并执行返回的js格式文件,此时js格式文件的数据作为参数,传入到了客户端预先定义好的callback函数(如$.ajax()方法封装的success: function(data)里。


 


5、jQuery用Ajax封装JSONP


远程服务器www.server.com根目录下的getResult.jsp文件动态生成的JS脚本:


serverResponse({
"name":"Amy",
"age":23,
"school":"BUPT"
});

本地服务器www.client.com根目录下的client.html文件:


<!DOCTYPE html>
<html>
<head>
<title></title>
  <script src=jquery-1.8.2.min.js"></script>
  <script>
     $(document).ready(function(){
        $.ajax({
            type: "get",
              async: false,
             url: "http://www.server.com/getResult.jsp?name=Amy",
             dataType: "jsonp",
             jsonp: "callback",
             jsonpCallback:"serverResponse",             
success: function(data){
                alert('年龄: ' + data.age + ',学校: ' + data.school);
             },
             error: function(){
                 alert(“跨域调用失败”);
             }
         });
     });
</script>
   </head>
<body>
  </body>
</html>



6、Ajax和JSONP


Ajax和JSONP在调用方式上看起来很像,目的也都是请求一个url,然后把服务器返回的数据进行处理,因此jQuery把JSONP作为Ajax的一种形式进行了封装。 


Ajax和JSONP本质上是不同的:Ajax的核心是通过XmlHttpRequest获取非本页内容,而JSONP的核心则是动态添加<script>标签来调用服务器提供的JS脚本。 


Ajax和JSONP的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。 


 


7、JSONP的优缺点


(1)优点


① 不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制,JSONP可以跨越同源策略;


② 兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持。


③ JSONP在请求完毕后可以通过调用callback的方式回传结果,将回调方法的权限给了调用方,相当于将controller层和view层终于分开了。JSONP服务只提供纯服务的数据,至于提供服务以后的页面渲染和后续view操作都由调用者来自己定义就好了。如果有两个页面需要渲染同一份数据,只需要有不同的渲染逻辑就可以了,逻辑都可以使用同一个JSONP服务。


2)缺点


① 只支持GET请求而不支持POST等其它类型的HTTP请求;


② 只支持跨域HTTP请求,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。


③ JSONP在调用失败时不会返回各种HTTP状态码。


④ 缺乏安全性。万一假如提供JSONP的服务存在页面注入漏洞,即它返回的JavaScript的内容被人控制的。那么所有调用这个JSONP的网站都会存在漏洞,于是无法把危险控制在一个域名下,所以在使用JSONP的时候必须要保证使用的JSONP服务必须是安全可信的。

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
廖雪
廖雪

78 篇文章

作家榜 »

  1. admin 651 文章
  2. 粪斗 185 文章
  3. 王凯 92 文章
  4. 廖雪 78 文章
  5. 牟雪峰 12 文章
  6. 李沁雪 9 文章
  7. 全易 2 文章
  8. Stevengring 0 文章