由于浏览器的同源策略禁止了跨域名调用,jsonp是一种跨域通信的手段,至于jsonp跨域原理,相信去百度应该会有一堆的答案,在这里我就不再多做阐述,下面直接上代码:
function jsonp(options){
return new Promise((resolve,reject)=>{
let callbackID=`jsonp_${Date.now()}_${Math.ceil(Math.random() * 100000)}`, //随机生成callbackID
container=document.getElementsByTagName('head')[0],
scriptNode = document.createElement("script"),
data = options.data || {},
url = options.url,
params = [];
data["callback"]=callbackID //加上callback参数,服务端接口数据根据callback返回函数
for (let key in data) { //遍历参数,把参数组成数组[name=zhangsan,age:18]
params.push(key+"="+data[key]);
}
url+= (/\?/.test(url))?'&':'?'; //判断原url是否已经有‘?’,如有给url拼接‘&’,则拼接‘?’
url+=params.join('&');
//url拼接参数最终变成www.baidu.com/?name=zhangsan&age=18&callback=jsonp_1526006949894_87849
scriptNode.id=callbackID; //设置script节点id以便后面删除
scriptNode.src = url;
window[callbackID]=function(response){
//定义全局函数,注意函数名是callbackID是跟上面定义的参数data["callback"]=callbackID是一致的
// 服务端接口是根据客户端传的callback而返回callbackID({"code":0,"error":"操作成功","data":{}})
resolve(response);
//当客服端请求接口时即调用了函数callbackID({"code":0,"error":"操作成功","data":{}}),刚好是这里我们定义
//的全局函数,于是就拿到了数据response
let script=document.getElementById(callbackID)
container.removeChild(script) //通过script节点id删除script节点
}
scriptNode.type = "text/javascript";
container.appendChild(scriptNode)
})}
jsonp({
url:"http://www.baidu.com/",
data:{name:"zhangsan",
age:18
}
}).then((res)=>{console.log('res',res)})
参考原文地址:https://segmentfault.com/a/1190000007665361