JSONP是一种解决跨域问题的方法,并不是一种数据格式(不同于JSON),是一种绕过同源策略实现跨域获取数据的解决方案,是一种非正式传输协议
一、同源策略:
要实现跨域,必须知道什么是同源策略?
同源策略是一种安全策略,所有支持JavaScript的浏览器都会使用同源策略
同源是指协议、端口、域名相同,不同源将无法请求到对应数据
一个网址:http://www.abc.com/page.html ,协议指 http:// ,域名是
www.abc.com
,端口是80
(默认端口可以省略),与以下网址的同源情况为:
http://www.abc.com/other.html
:同源https://www.abc.com/other.html
:不同源(协议不同)http://v2.www.abc.com/other.html
:不同源(域名不同)http://www.abc.com:81/other.html
:不同源(端口不同)
同源政策的目的是为了保证用户信息的安全,防止恶意的网站窃取数据(如防止Cookie数据被窃取)
二、JSONP原理
由于img、srcipt,link标签的src或href属性不受同源策略的约束,可以利用这一特点实现跨域请求数据
具体操作:
1、动态创建script标签,并将远程接口赋值给script.src,示例为百度搜索的接口,wd的值为用户搜索的关键字,cb的值为回调函数的名称
var script = document.createElement('script');
var url = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/?wd=?&cb=";//cb是callback的缩写
script.src = url;
2、创建回调函数处理获得的数据
function handlerJsonp(data){
console.log(data);
//这里自定义处理数据的方法
}
3、将回调函数的函数名添加到远程接口上,即修改src中callback的值,并将script标签添加到body中
var url = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/?wd=&cb=handlerJsonp";
document.body.appendChild(script);
这样,就利用JSONP原理实现跨域了。
总结:JSONP实现跨域,是利用src或href属性不受同源策略限制的特点,动态创建script标签,将远程接口赋值给src获取数据,并通过回调函数来接受和处理数据,达到跨域的目的。
下面是一个利用百度搜索接口实现JSONP跨域的示例
<div class="wrap">
<input id="txt" type="text"><span><a href="">百度一下</a></span>
<ul id="ulinfo"></ul>
</div>
<script>
var txt = document.getElementById('txt');
var ulinfo = document.getElementById('ulinfo');
txt.onkeyup = function(){
//防止生成多个script标签
if(document.querySelector("#jsonp")){
document.querySelector("#jsonp").remove();
}
//获取用户搜索的关键字
var word = this.value;
//动态创建script标签
var script = document.createElement('script');
script.id = 'jsonp';
//将关键字和回调函数名传入到接口中
var url = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/?wd="+ word +"&cb=handlerJsonp";
//将url赋值给src属性
script.src = url;
document.body.appendChild(script);
}
//自定义回调函数,用来处理获得的数据
function handlerJsonp(result){
console.log(result);
var str ='';
for(var i = 0; i < result.s.length; i++){
str += '<li><a href="">' + result.s[i] + '</a></li>';
}
ulinfo.innerHTML = str;
}
</script>
三、jquery如何实现jsonp跨域?
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回调函数名称
success: function(json){
console.log(data);
//自定义处理数据的方法
},
error: function(){
alert('err');
}
});
});
虽然jquery把jsonp的实现封装到了ajax中,但jsonp的实现与ajax的实现原理根本不是一回事。ajax的核心是通过XMLHttpRequest获取非本页内容,而jsonp的核心则是通过HTTP来动态添加 <script>
标签来调用服务器提供的js脚本
四、JSONP的优缺点
优点:
- 不受同源策略的限制
- 兼容性好,在老版本浏览器中仍可运行,不需要XMLHttpRequest或ActiveX的支持
- 在请求完毕后可以通过调用callback的方式回传结果,将回调方法的权限给了调用方、
缺点:
- 只支持GET请求而不支持POST等其它类型的HTTP请求
- 只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题
- jsonp在调用失败的时候不会返回各种HTTP状态码
- 存在一定的安全问题