版权声明:本人原创文章,转载请注明出处 https://blog.csdn.net/qq_28766729/article/details/85004449
Jsonp解释
Jsonp这个术语听起来很高大上,其实它的原理非常简单,就是利用src不受同源策略限制这一点来实现的,很多标签都有src特性。
你们可以想想为什么img标签能将不同源的百度logo拿过来?
<img src="https://www.baidu.com/img/bd_logo1.png" alt="">
Jsonp原理
一、src不受同源策略的限制,不受跨域的影响,所以可以借助script中的src属性进行跨域获取数据。
二、所以将数据放到服务器上,并且数据为json形式,因为js可以轻松处理json数据。
三、由于我们动态创建的script标签是一个异步加载的过程,不确定数据什么时候回来,所以要做个处理,在前端写好一个function并将函数名传给服务器,后端拿到函数名,完成一个拼接 functionName(parameter),将json数据以入参的方式放置在function中,生成js语法的文档,返回给客户端。此时客户端继续解析,将json数据作为参数,传入之前定义好的callback函数中。
四、所以根据第三步,需要先写好函数来处理跨域获取的数据。
五、用src获取数据的时候,在url后边添加一个参数,例如cb = xxx,服务端会将cb的值,对应为一个函数,将参数插入到其中,例如 xxx(parameter)
注意
基于JSONP的实现原理,所以JSONP只能是“GET”请求,不能进行较为复杂的POST和其它请求,所以遇到那种情况,就得参考CORS解决跨域了(所以如今它也基本被淘汰了)。
下面代码演示如何使用Jsonp来实现跨域请求百度搜索接口,完成联想词功能,这里先用原生JS来实现,能更好理解实现原理。在jQuery的ajax里封装了Jsonp和CORS跨域解决办法,后期会进行讲解。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>百度搜索框</title>
<style>
*{
padding: 0;
margin: 0;
list-style: none;
}
input{
width: 400px;
height: 34px;
}
ul{
display: none;
width: 400px;
border: 1px solid #ccc;
}
li{
margin-left: 10px;
margin-top: 3px;
}
.wrapper{
margin: 100px;
}
a{
text-decoration: none;
color: #666;
font-size: 14px;
}
</style>
</head>
<body>
<div class="wrapper">
<input type="text">
<ul>
</ul>
</div>
<script src="jquery.js"></script>
<script>
function ds(data) {
console.log(data)
}
/*通过jsonp访问百度服务器,获取搜索联想词*/
var oInput = document.getElementsByTagName("input")[0];
oInput.oninput = function () {
var value = this.value;
var oScript = document.createElement("script");
//wd=关键字,doJson=执行函数名,这里要保证传的是函数名的字符串!!!
oScript.src = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+ value +"&cb=doJson&_=1544270132010";
//这里将插入以联想词数组为参数的名为doJson的js文件,马上执行
document.body.appendChild(oScript);
//执行完以后又马上移除掉
document.body.removeChild(oScript);
};
function doJson(data) {
var s = data.s;
$("ul").empty();
//当输入值过多时,s的联想词会匹配不到
if(s.length > 0){
s.forEach(function (ele,index) {
var a = $("<a></a>").attr("href","https://www.baidu.com/s?wd=" + ele);
a.text(ele);
$("<li></li>").append(a).appendTo($("ul"));
});
$("ul").css("display","block");
}else{
$("ul").css("display","none");
}
}
</script>
</body>
</html>