学习资料来源:【原创】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
同源政策
所谓“同源”指的是”三个相同“
- 协议相同
- 域名相同
- 端口相同
如果非同源,共有三种行为受到限制。
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB。
- 无法接触非同源网页的 DOM。
- 无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)。
跨域
不同域之间相互请求资源
JSONP
Jsonp (JSON with Padding)
Jsonp的产生:
- 受同源策略影响,Ajax直接请求普通文件存在跨域无权限访问的问题
- 与此同时,Web页面上调用js文件时则不受是否跨域的影响(凡是拥有”src”这个属性的标签都拥有跨域的能力,比如
<script>
、<img>
、<iframe>
) - 通过纯web端跨域访问数据可以采取这种方式:在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理。
- 恰巧JSON的纯字符数据格式可以简洁的描述复杂数据,且JSON还被js原生支持。
- web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀)
- 为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
实现JSONP思路:(以查询航班信息为例)
- 请求方用JS创建一个script标签,它的src指向响应方,同时传查询参数(?callback=…)
var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
// 创建script标签,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
- 用
document.body.appendChild(script)
将它添加进页面中 - 服务端(响应方)把需求的数据包裹进请求方给的函数名中
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
- 请求方根据自己的需要处理数据
// 得到航班信息查询结果后的回调函数
var flightHandler = function(data){
alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
};
jquery的写法
<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>
JSONP不支持POST请求,因为JSONP是通过动态创建script的方法进行的,而script只能发送get请求不能发送post请求。
ajax与jsonp的异同
- ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装;
- 但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加
<script>
标签来调用服务器提供的js脚本。 - 所以说,其实ajax与jsonp的区别不在于是否跨域,ajax通过服务端代理一样可以实现跨域,jsonp本身也不排斥同域的数据的获取。
- 总而言之,jsonp不是ajax的一个特例,哪怕jquery等巨头把jsonp封装进了ajax,也不能改变着一点!