jsonp解决第三方接口跨域问题

什么是jsonp

  1. 一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准;
  2. 不过我们又发现,web页面上调用js文件时不受是否跨域的影响(不仅如此,凡是拥有”src”这个属性的标签都拥有跨域能力,如<script>、<img>、<iframe>

  3. 于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;

  4. 恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;

  5. 这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。

  6. 客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但其实并不一样

  7. 为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了

原生jsonp解决跨域问题

使用原生jsonp解决跨域问题需要两个步骤

  1. 定义一个函数,负责解析jsonp接口传过来的数据,就是下面例子传过来的天气数据
  2. 调用接口,调用方式使用创建一个script标签,添加到页面上

天气查询实例

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>获取第三方天气数据</title>
    <style type="text/css">
        #div1{
            position:relative;
            left: 50%;
            background: lightGreen;
            width: 300px;
            height: 500px;
            overflow-y: scroll;
            overflow-x: hidden;
            margin-left: -150px;
            padding-bottom: 20px;
        }
        #div1 select{
            margin-left : 80px;
            margin-top : 10px;
            height: 30px;
        }
        #div1 input{
            height: 30px;
        }
        #div1 div{
            width: 300px;
            background: lightBlue;
            border-bottom: red solid 1px;
        }
        #div1 div ul li{
            list-style-type: none;  
            padding-left: 10px;
        }


    </style>
    <script type="text/javascript">
    function abc(data){
        var d = data.weather;
        var info = document.getElementById('info');
        info.innerHTML = '';

        for(var i=0;i<d.length;i++){
            var date = d[i].date;
            var day = d[i].info.day;
            var night = d[i].info.night;
            var tag = '';
            tag += '<span>日期:'+date+'</sapn><ul>';
            tag += '<li>白天天气:'+day[1]+'</li>'
            tag += '<li>白天温度:'+day[2]+'</li>'
            tag += '<li>白天风向:'+day[3]+'</li>'
            tag += '<li>白天风速:'+day[4]+'</li>'
            tag += '</ul>';

            tag += '<ul>';
            tag += '<li>夜间天气:'+night[1]+'</li>'
            tag += '<li>夜间温度:'+night[2]+'</li>'
            tag += '<li>夜间风向:'+night[3]+'</li>'
            tag += '<li>夜间风速:'+night[4]+'</li>'
            tag += '</ul>';
            var div = document.createElement('div');
            div.innerHTML = tag;
            info.appendChild(div);

        }
    }

    window.onload = function(){
        var city = document.getElementById('city');
        city.onchange = function(){
            document.getElementById('info').innerHTML = '';
        }
        var btn = document.getElementById('btn');

        btn.onclick = function(){
            var cityCode = city.value;
            var url = 'http://cdn.weather.hao.360.cn/api_weather_info.php?app=hao360&_jsonp=abc&code='+city.value;
            var script = document.createElement('script');
            script.src = url;
            document.body.appendChild(script);
        }

    }
    </script>
</head>
<body>
<div id="div1">
    <select id="city">
        <option value="101010100">北京</option>
        <option value="101020100">上海</option>
        <option value="101280101">广州</option>
        <option value="101280601">深圳</option>
    </select>
    <input type="button" value="查看天气" id="btn">
    <div id="info"></div>
</div>
</body>
</html>

jquery对jsonp的实现

jquery在处理jsonp类型的ajax时,自动生成回调函数并把数据取出来供success属性方法来调用

<!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>

ajax与jsonp的异同之处

1.ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;

2.但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加

客官,打赏一下嘛~~