jsonp原理
通过动态创建标签,利用script标签的src属性能够引入外部脚本的特性,动态引入一段js代码;相当于前端给服务端一个jsonp访问的标记,服务端返回一个可执行的callback函数,该函数的参数就为所请求的数据。
使用jsonp的场景与条件
使用场景:需要跨域访问获取数据,并且安全性要求不是很高
使用条件:服务端需要提供jsonp访问的接口
jsonp访问的简单封装
var JSONP = function(config){
var config = config || {},
url = config.url || null, // 请求地址
data = config.data || null, // 参数
callback = config.callback || null, // 回调函数
cbKey = config.cbKey || null; // 回调函数标识 (key)'cb=callback'
if(!url){
throw Error('url is required!');
}
var name = "id_"+ (new Date()).getTime();
var srcUrl = getSrcUrl(url, data, name, cbKey);
var script = document.createElement('script');
script.type = "text/javascript";
script.src = srcUrl;
script.id = name;
window[name] = function(json){
window[name] = undefined;
var elem = document.getElementById(name);
removeElem(elem);
callback && typeof callback === 'function' && callback(json);
}
var head = document.getElementsByTagName('head');
if(head && head[0]){
head[0].appendChild(script);
}
}
var getSrcUrl = function(url, data, name, cbKey){
var _url = url + (url.indexOf('?') === -1 ? '?' : '&'),
ret = '';
if(typeof data === 'string'){
ret = data;
}else if(typeof data === 'object'){
for(var key in data){
ret += '&' + key + '=' + encodeURIComponent(data[key]);
}
}
if( cbKey ){
ret += '&' + cbKey + '=' + name;
}else{
ret += '&' + name;
}
ret = ret.substr(1);
return _url + ret;
}
var removeElem = function(elem){
var parent = elem.parentNode;
if(parent && parent.nodeType !== 11){
parent.removeChild(elem);
}
}
jsonp使用示例(借用百度搜索接口,搜索框输入文字动态匹配搜索结果)
<!DOCTYPE>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
#wrap{
width: 200px;
margin: 100px auto;
}
#txt {
width: 400px;
height: 40px;
}
#list{
width: 400px;
border:1px solid #ccc ;
border-top:0;
display: none;
}
#list li{
list-style: none;
width: 100%;
height: 25px;
font-size: 14px;
font-family: "微软雅黑";
line-height: 25px;
}
#list li a{
text-decoration: none;
color: #333;
display: block;
width: 100%;
height: 25px;
font-weight: 600;
}
#list li a:hover{
background: #eee;
}
</style>
</head>
<body>
<div id="wrap">
<input type="text" name="txt" id="txt" value="" />
<ul id="list">
</ul>
</div>
<script src="./jsonp.js"></script>
<script>
var elTxt = document.getElementById('txt'),
elList = document.getElementById('list'),
elA = elList.getElementsByTagName('a');
elTxt.addEventListener("keyup", function(e){
var e = e || event;
if(e.keyCode != 38 && e.keyCode != 40 && e.keyCode != 13){
var val = elTxt.value;
// 使用 jsonp 请求
JSONP({
url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
data: {wd: val},
cbKey: 'cb',
callback: function(response){
var dataList = response.s;
renderList(dataList)
}
})
}
})
var renderList = function(data){
console.log(data)
if(data && data.length > 0){
var str = '';
for(var i = 0, len = data.length; i < len; i++){
str += '<li><a href="https://www.baidu.com/s?wd='+data[i]+'" target="_blank">'+data[i]+'</a></li>'
}
elList.innerHTML = str;
elList.style.display = 'block';
}else{
elList.innerHTML = null;
elList.style.display = 'none';
}
}
</script>
</body>
</html>