Can
Be Better

Json与Jsonp

序言

出来混迟早是要还得!!!恶补JS知识,不要在逃避了

最近借鉴别人的思路看到这么一段代码:

function GetModel() {
            var data = $("#FrmMote").serialize();
//            alert(model_host + "/bin/Test.dll/MainPage?" + data);
            console.log("In GetModel function var data is :"+model_host + "/bin/Test.dll/MainPage?" + data);
            $.ajax({
                type: "get",
                async: false,
//            url: model_host + "/bin/Test.dll/MainPage?mote=" + FrmMote.mote.value + "&Bu=" + FrmMote.Bu.value + "&globgid=" + FrmMote.globgid.value + "&IsResponeFilePath=1",
                url: model_host + "/bin/Test.dll/MainPage?" + data,
                dataType: "jsonp",
                jsonp: "callback",
                jsonpCallback: "success_jsonpCallback",
                success: function (json) {
                    model_waiting = false;
                    $("#bigImgShow").attr("src", json.imgBm);
//                $('#bigImgShow').show();
//                $('.mod_operate').show();
                    $('.mod_loading').hide();
                },
                error: function (e, a) {
                    alert(a);
                }
            });
        }

一眼看上去本以为是普通的ajax调用。但是明明写的明明白白,是Jsonp。好吧,相差一个字母也不能想当然。

同源策略

URL 说明 是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下 允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不同文件夹 允许
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不同端口 不允许
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同协议 不允许
http://www.a.com/a.js
http://70.32.92.74/b.js
域名和域名对应ip 不允许
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不同 不允许
http://www.a.com/a.js
http://a.com/b.js
同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js
http://www.a.com/b.js
不同域名 不允许
特别注意两点:
第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,
第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。
好吧,其实这样比较好理解。
1.随便建两个网页一个端口是2698,一个2701,按照定义它们是不同源的。image_thumb4

2.用jQuery发起不同源的请求

在2698端口的网页上添加一个按钮,Click事件随便发起两个向端口为2701域的请求。

$("#getOtherDomainThings").click(function () {
    $.get("http://localhost:2701/Scripts/jquery-1.4.4.min.js", function (data) {
        console.log(data)
    })

    $.get("http://localhost:2701/home/index", function (data) {
        console.log(data)
    })
})

根据同源策略,很明显会悲剧了。浏览器会阻止,根本不会发起这个请求。(not allowed by Access-Control-Allow-Origin)

image_thumb8

OK,原来jsonp是要解决这个问题的。

代码实例

上面说那么多,主要是说明为什么要用Jsonp。大家的时间都很宝贵,遇到问题在静心阅读真的很烦哟。下面直接上代码:

代码1

前端 Jquery

<!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.php?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时(还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮你生成回调函数并把数据取出来供success属性方法来调用

后端 PHP

flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
});

 

代码2

前端

<script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>  
        <script type="text/javascript">  
            $(function(){  
                  $.ajax({  
                       url : "http://192.168.1.130/mytest/mytest.php",  
                       dataType:"jsonp",  
                       data:{  
                           "id":"123456",  
                           "t":1  
                       },  
                       type:"post",  
                       jsonp:"jsonpcallback",  
                       timeout: 5000,  
                       success:function(data){  
                           console.log(data);  
                       },  
                       error:function(XHR, textStatus, errorThrown){  
                           console.log('error: ' + textStatus);  
                           console.log('error: ' + errorThrown);  
                       }  
                  });  
            });  
        </script>

后端

<?php  
  
$id = $_POST['id'];  
$t = $_POST['t'];  
  
$jsonp = $_GET['jsonpcallback'];//get接收jsonp自动生成的函数名  
  
$arr = array(  
    'id' => $id,  
    't' => $t  
);  
echo $jsonp.'('. json_encode($arr). ')'; //jsonp函数名包裹json数据  
  
  
?>

运行结果:

不开启评论,如有问题疑问请发邮件。[email protected]最长的路 » Json与Jsonp

评论 抢沙发

评论前必须登录!