前言
Hi~ 之前在掘金里写了一篇关于JSONP请求的博客,简述了JSONP的相关概念以及使用。
传送门:一分钟说完JSONP请求,面试满分答案ヾ(≧▽≦*)o
这篇分享的东西算是对上文的一种补充,让大家通过代码更为形象的了解JSONP请求
思路
图示:
关键点:
- 每次请求完成之后,必须清空产生的多余无用的方法和标签
- 包装成promise对象,使用起来就像axios一样
- 自动生成接收函数,无需用户考虑,我们要做的是把值传递回去
代码实现
话不多说,先上代码
function myJsonp(options) {
return new Promise((resolve, reject) => {
//判断是否是第一次jsonp请求
if (!window.jsonpNum) {
window.jsonpNum = 1
} else {
window.jsonpNum++
}
let {
url,
data,
timeout = 5000,
cbkey = 'callback',
} = options
//保证每次请求接收的方法都不会重复
let funName = 'jsonpReceive' + window.jsonpNum
//清除本次jsonp请求产生的一些无用东西
function clear() {
window[funName] = null
script.parentNode.removeChild(script);
clearTimeout(timer)
}
//定义jsonp接收函数
window[funName] = function(res) {
//一旦函数执行了,就等于说请求成功了
resolve(res)
clear()
}
//请求超时计时器
let timer = setTimeout(() => {
reject('超时了')
clear()
}, timeout)
//定义请求的参数
let params = ''
//如果有参数
if (Object.keys(data).length) {
for (let key in data) {
params += `&${key}=${encodeURIComponent(data[key])}`;
}
params = params.substr(1)
}
//拼接最终的请求路径,结尾拼接回调的方法名
url = url + '?' + params + `&${cbkey}=${funName}`
let script = document.createElement('script');
script.src = url;
document.body.appendChild(script);
})
}
复制代码
调用
-
测试QQ音乐获取首页轮播图的JSONP接口
let options = { url:'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg', cbkey: 'jsonpCallback', data: { g_tk: 1928093487, inCharset: 'utf-8', outCharset: 'utf-8', notice: 0, format: 'jsonp', platform: 'h5', uin: 0, needNewCode: 1 }, // QQ音乐接口Jsonp字段 } myJsonp(options) .then(res => { console.log(res); },err=>{ console.log(err) }) 复制代码
-
结果