用promise实现可靠的jsonp插件

由于浏览器的同源策略禁止了跨域名调用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

你可能感兴趣的:(js)