Jsonp的跨域问题,再讲以前先说明一下什么是同源策略。javascript
来自百度的介绍
同源策略,它是由Netscape提出的一个著名的安全策略。如今全部支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面。当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪一个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。若是非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。php
以下:下表引自网络其余博客大牛html
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: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 |
同一域名,不一样二级域名(同上) | 不容许 |
http://www.cnblogs.com/a.js http://www.a.com/b.js |
不一样域名 | 不容许 |
Json 和jsonp看起来好像啊,那么他们之间有什么联系吗?
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,其具体格式及用法,个人这篇文章有介绍XML与JSON比较,并用AJAX传输XML/JSON数据
JSONP 是JSON with Padding的简称,它是一个非官方的协议,它容许在服务器端集成Script tags返回客户端,经过javascript callback的形式实现跨域访问。(这是百度的说法,不懂不要紧,我细细讲解)java
来看个小例子,你们还接标签吗,咱们知道标签中的src属性能够引用本地资源,那么我要是访问网上的资源能够吗.行不行的通,试试看。举例,请求百度的logo吧,百度logo地址为:
https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.pngjquery
html页面web
<div id="bdlog">
<img src="https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png">
</div>
结果展现:ajax
看到了吧,<img>
中的src属性既能够请求本地图片,也能够请求网上资源。也就是说html中的src属性是支持跨域的。同理jsonp跨域请求也是利用src属性,只不过用的是<script></script>
标签。
来看个jsonp的小例子
jsonp.htmljson
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp请求资源</title>
</head>
<body>
</body>
</html>
<script type="text/javascript" src="js/data.js
data.js后端
console.log("我被jsonp请求了!");
打开控制台,看一下:
看,jsonp实现了本地数据的请求。若是我想请求服务器的数据该是怎样去实现呢?跨域
jsonp.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp请求服务器数据</title>
</head>
<body>
</body>
</html>
<script type="text/javascript" src="http://127.0.0.1/2017_06_26/jsonp/02jsonp.php"></script>
jsonp.php
<?php echo "成功请求服务器!"; ?>
结果以下:
咱们会发现页面请求了 jsonp.php页面,而且使用的是get方法。也就是说jsonp请求数据默认使用的是get方法。刚才咱们再介绍jsonp的时候,说了一下 容许在服务器端集成Script tags返回客户端,经过javascript callback的形式实现跨域访问。
那么咱们继续改进html页面,在请求的url中添加一个?callback=test参数.其中test是写在html中的js函数
jsonp.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp请求服务器数据</title>
</head>
<body>
</body>
</html>
<script> function test(data) { console.log("测试可否调用我这个test()函数"); console.log(data); } </script>
<script type="text/javascript" src="http://127.0.0.1/2017_06_26/jsonp/jsonp.php?callback=test"> </script>
jsonp.php
<?php // 获取到了 test.() 返回的是 test({"name":"jsonp","color":"green"}); echo $_GET['callback'].'({"name":"jsonp","color":"green"})'; ?>
结果是:
经过script标签引入一个js文件,这个js文件载入成功后会执行咱们在url拼接一个callback参数,经过get方式请求服务器,服务器返回的数据如果json字符串将自动转化为js对象。因此jsonp是须要服务器端和客户端相互配合的。
看图也许会明了一些:
可是每次写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jQuery发送jsonp请求</title>
</head>
<body>
<input type="button" value="jQuery发送jsonp请求" id="jq_jsonp">
</body>
</html>
<!--导入jQuery-->
<script type="text/javascript" src="js/jquery.min.js"></script>
<script> $(function () { $('#jq_jsonp').click(function () { $.ajax({ url:'jQ_jsonp.php', success:function (data) { console.log(data); }, dataType:'jsonp' }) }) }) </script>
能够发现,咱们并无写callback方法,jQuery自动帮咱们封装了一个callback方法。
若是想要设置 本身的 回调函数 能够经过jsonpCallback 来设置 本身的名字
<script> function myJSONPCallback(data) { console.log("本身写的callback函数"+data); } $(function () { $('#jq_jsonp').click(function () { $.ajax({ url:'jQ_jsonp.php', success:function (data) { console.log(data); }, dataType:'jsonp', jsonpCallback:"myJSONPCallback" }) }) }) </script>
jQ_jsonp.php
<?php echo $_GET['callback'].'("哈哈哈")'; ?>
总结:JSONP(JSON with Padding)其本质是利用了<script src=""></script>
标签具备可跨域的特性,由服务端返回一个预先定义好的Javascript函数的调用,而且将服务器数据以该函数参数的形式传递过来,此方法须要先后端配合完成。**
只能以GET方式请求.**