// jsonp.js
export default (options) => {
if (!options || !options.url) return
let id = 0 // 用于生成callback函数名
let header = document.querySelector('head')
let script = document.createElement('script')
let url = options.url let data = options.data || {}
let callback = options.callback let fnName = "jsonp" + id++
// 添加回调函数名
data[options.param] = fnName
// 拼接url
let params = []
for (let key in data) {
if(data[key]) {
params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)
}
}
url += url.indexOf('?') > 0 ? '&' : '?'
url += params.join('&')
script.src = url
// 将传递的是一个匿名的回调函数暴露为一个全局方法
window[fnName] = function(res) {
callback && callback('', res)
header.removeChild(script)
delete window[fnName]
}
// 出错处理
script.onerror = function(){
callback && callback({error: 'error'})
header.removeChild(script)
window[fnName] && delete window[fnName]
}
script.type = 'text/javascript'
header.appendChild(script)
}
// 用promise封装使用jsonp
// promise.js
import jsonp from "./jsonp";
export default (url, data, opt) => {
return new Promise((resolve, reject) => {
jsonp({
url: url,
data: data,
param: opt.param
callback: function (err, res){
if (!err) {
resolve(res)
} else {
reject(err)
}
}
}, opt)
})
}
// 写qq音乐的接口
// api.js
import promise from "./promise"
export default () => {
// qq音乐的推荐页面对应的接口
let url = 'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg'
// 可以去qq音乐网页打开network看对应的参数
let data = {
g_tk: 1928093487,
inCharset: 'utf-8',
outCharset: 'utf-8',
notice: 0,
format: 'jsonp',
platform: 'h5',
uin: 0,
needNewCode: 1
}
// jsonp请求时与后台协商的callback名,qq音乐是'jsonpCallback'
let opt = {
param: 'jsonpCallback'
}
return promise(url, data, opt)
}
// 测试
// test.js
import music from "./api"
music().then(res => {
console.log(res)
})