原理:利用<script>标签的src属性并不被同源策略所约束即可以跨域的特性,获取任何服务器上脚本并执行,只能通过GET方式传递.你不能访问响应信息头或者像访问字符串那样访问整个响应报文;
JSONP由两部分组成:回调函数和数据;回调函数是响应到来时应该在页面中调用的函数,回调函数的名字一般是在请求中指定的或者是默认的;而数据就是传入回调函数中的JSON数据;
注意点:script标签只能是DOM生成插入head标签内的;不能使用obj.innerHTML="",这样src属性不能执行;
如:百度的Jsonp接口 https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=jsonp&json=1&p=3&sid=22078_1428_21112_17001_22035&req=2&csor=2&pwd=w&cb=show
其中:“wd=”里面就是搜索的关键字;“cb=”里面就是callback;
调用接口返回的结果为:
show({"q":"jsonp","p":false,"bs":"","csor":"2","status":0,"g":[ { "q": "json", "t": "n", "st": { "q": "json", "new": 0 } }, { "q": "jsonp 跨域", "t": "n", "st": { "q": "jsonp 跨域", "new": 0 } }, { "q": "jsonp post", "t": "n", "st": { "q": "jsonp post", "new": 0 } }, { "q": "jsonp callback", "t": "n", "st": { "q": "jsonp callback", "new": 0 } }, { "q": "jsonp原理", "t": "n", "st": { "q": "jsonp原理", "new": 0 } }, { "q": "jsonpath", "t": "n", "st": { "q": "jsonpath", "new": 0 } }, { "q": "jsonparser", "t": "n", "st": { "q": "jsonparser", "new": 0 } }, { "q": "jsonp的原理", "t": "n", "st": { "q": "jsonp的原理", "new": 0 } }, { "q": "json.parse()", "t": "n", "st": { "q": "json.parse()", "new": 0 } }, { "q": "json.parse", "t": "n", "st": { "q": "json.parse", "new": 0 } } ],"s":["json","jsonp 跨域","jsonp post","jsonp callback","jsonp原理","jsonpath","jsonparser","jsonp的原理","json.parse()","json.parse"]});
百度接口使用代码:
<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=jsonp&json=1&p=3&sid=22078_1428_21112_17001_22035&req=2&csor=2&pwd=w&cb=show"></script>
//定义callback函数
function show(json){
// 要执行的代码
}
//执行
show(json);
为了使用方便,我们需要封装一个Jsonp函数,方便使用:
function jsonp(json){
var json = json || {};
if(!json.url){
return;
}
json.data = json.data || {};
json.cbName = json.cbName || 'cb';
var fnName = 'jsonp_'+Math.random();
//把随机数里面的"."去掉
fnName = fnName.replace('.','');
var oS = document.createElement('script');
json.data[json.cbName] = fnName;
var arr = [];
for(var name in json.data){
arr.push(name + '=' + json.data[name]);
}
oS.src = json.url + '?' + arr.join('&');
var oHead = document.getElementsByTagName('head')[0];
oHead.appendChild(oS);
window[fnName] = function(json2) {
json.success && json.success(json2);
//创建的script标签使用完,删除
oHead.removeChild(oS);
}
}
网友评论