jsonp的基础理解-简单易懂

因为参加春招面试,一面被问到跨域的问题,当时一脸懵,之后了解了之后知道jsonp是一个比较典型的跨域方法,但是看了很多博客和讲解并不是很能理解,所以根据自己所看的简单总结。

一、JSONP产生的过程

1、众所周知,ajax需要满足同源策略,所以直接请求存在跨域问题的一切文件,都会报错。
2、但是当我们在编写html页面时,会发现有些特殊标签不受跨域的影响,比如:调用js文件和拥有src属性的标签(<\img><\script><\link><\iframe>等)。
3、于是可以判断,当前阶段想要通过web页面跨域访问就只有一个可能,就是在远程服务器上设法将数据装入js文件里,供客户端调用和进一步处理。
4、为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们称作JSONP,**该协议的一个要点就是允许用户传递一个callback参数给服务器端,然后服务器端返回数据时会将这个callback参数作为函数名来包裹住的JSON数据,**这样客户端就可以随意搭建自己的函数来处理返回数据了。

二、JSONP的实现

1、我们知道,跨域js文件中的代码,web页面可以无条件执行,
2、当在jsonp.html页面定义一个函数,然后在远程remote.js传入数据进行调用。
jsonp.html代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>
<body>
 
</body>
</html>

remote.js文件代码如下:

localHandler({"result":"我是远程js带来的数据"});

3、上面跨域存在一个问题,就是当jsonp的服务器面对很多服务对象,这些服务对象的本地函数都不相同,怎样来确定当前调用的是哪个函数呢?
解决方法就是动态生成js脚本,可以传递一个参数告诉服务器:“我需要xxx函数的js代码,请返回给我。”,于是服务器可以按要求生成js脚本并响应了。
jsonp.html代码:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>
 
</body>
</html

此处的callback参数告诉服务器,我的本地回调函数叫做flightHandler,所以请把查询结果传入这个函数中进行调用。
4、最后,jsonp的实现原理基本梳理结束,剩下的就是利用ajax进行封装,以便于与用户界面交互,从而实现多次和重复调用。
jQuery如何实现jsonp:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
     <title>Untitled Page</title>
      <script type="text/javascript" src=jquery.min.js"></script>
      <script type="text/javascript">
     jQuery(document).ready(function(){ 
        $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
             jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
             success: function(json){
                 alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
             },
             error: function(){
                 alert('fail');
             }
         });
     });
     </script>
     </head>
  <body>
  </body>
</html>

jQuery在处理jsonp类型的ajax时,自动帮你生成回调函数并把数据取出来供success属性方法调用。上面可以看出将jsonp归入ajax进行调用也实现了跨域请求,是不是可以说明ajax和jsonp是一回事?答案是否定的。

ajax和jsonp的异同:

(1)ajax和jsonp这两种技术在调用方式上看起来很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jQuery和ext等框架都把jsonp作为ajax的一种形式进行了封装。
(2)但是ajax和jsonp其实本质上是不同的东西,ajax的核心是通过XMLHttpRequest获取非本页内容,而jsonp的核心则是动态添加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值