JSONP的使用及原理

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服务必须是安全可信的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.duanlonglong.com/qdjy/395.html