序言
出来混迟早是要还得!!!恶补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,按照定义它们是不同源的。
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)
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数据 ?>
运行结果: