问题如下参考链接:https://segmentfault.com/q/1010000010051040
用jsonp抓取qq音乐总是说回调函数没有定义,
我的要实现时候的步骤
1。第一步
我要实现的目的
问题:如题
我的部分代码:
import originJSONP from 'jsonp'
export default function (url, data, option) {
url += (url.indexOf('?') < 0 ? '?' : '&') + param(data)
return new Promise((resolve, reject) => {
originJSONP(url, option, (err, data) => {
if (!err) {
resolve(data)
} else {
reject(err)
}
})
})
}
// 将 data 拼接到 url 上
function param(data) {
let url = ''
for (let i in data) {
let value = data[i] !== undefined ? data[i] : ''
url += `&${i}=${encodeURIComponent(value)}`
}
return url
}
// 热门歌单详情歌曲
export function getHotSongList(disstid) {
const url = 'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg'
const data = Object.assign({}, commonParam, {
type: 1,
json: 1,
utf8: 1,
onlysong: 0,
disstid,
// jsonpCallback: 'playlistinfoCallback',
loginUin: 0,
hostUin: 0,
inCharset: 'utf8',
platform: 'yqq',
needNewCode: 0
})
return jsonp(url, data, options)
}
// this.disc.dissid我已经正确获取了,通过自己服务端代理,代码太多就不贴了。
// TODO 报错ReferenceError: jp1() is not defined
getHotSongList(this.disc.dissid).then((res) => {
if (res.code === ERR_OK) {
// 问题 不能打印出来
console.log(res.cdlist[0].songlist)
}
})
不知道为甚么,折腾一天了,还是没解决,是QQ音乐的接口变了吗,(前两天同样的代码还能正常运行的,昨天就不行了),希望有大神帮忙看看是怎么回事,先谢谢大家了。
补充
回调函数的名称里边处理好了,对其他接口(歌曲图片,歌手,都是用jsonp获取没有问题),_jp1是一个默认名称而已。请求第二个它就变成_jp2,如此类推
处理的部分代码
// 库它自己定义的名字
var prefix = opts.prefix || '__jp';
// use the callback name that was passed if one was provided.
// otherwise generate a unique name by incrementing our counter.
var id = opts.name || (prefix + (count++));
该库的地址:https://github.com/webmodules...
再次补充
修改options回调函数名字貌似不行,需要再次设置反向代理,即可解决问题,建议大家看一下MJingv的github相关反向代理设置,地址:https://github.com/MJingv/vue...
单纯这个错误Uncaught ReferenceError: jp2 is not defined,
export function getSongList (disstid) {
const url = 'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg'
const data = Object.assign({}, commonParams, {
disstid,
type: 1,
json: 1,
utf8: 1,
onlysong: 0,
hostUin: 0,
g_tk: 487535770,
platform: 'yqq',
needNewCode: 0
})
return jsonp(url, data, options)
}
利用如下方法解决
仔细阅读一下第三方库jsonp,里面的opts是一个对象,prefix属性表示callback返回的名字,即传参时候的val值,默认是"__jp",param属性表示的是传参时候的key值。
修改方法,把options定义为:
export function getSongList (disstid) {
const url = 'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg'
const data = Object.assign({}, commonParams, {
disstid,
type: 1,
json: 1,
utf8: 1,
onlysong: 0,
hostUin: 0,
g_tk: 487535770,
platform: 'yqq',
needNewCode: 0
})
const options = {
param: 'jsonpCallback',
prefix: 'playlistinfoCallback'
}
return jsonp(url, data, options)
}
这样把问题解决了,但是还是获取不到数据
确实不能通过jsonp的方式了,参照以前的接口,用node做转发层。
app.get('/api/getSongList', function (req, res) {
var url = 'https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg'
axios.get(url, {
headers: {
referer: 'https://y.qq.com/',
host: 'c.y.qq.com'
},
params: req.query
}).then((response) => {
var ret = response.data
if (typeof ret === 'string') {
// var reg = /^\w+\(({[^()]+})\)$/
var reg = /{.*}/
var matches = ret.match(reg)
if (matches) {
ret = JSON.parse(matches[0])
}
}
res.json(ret)
}).catch((e) => {
console.log(e)
})
})
在请求接口的地方用axios请求
export function getSongList(disstid) {
const url = '/api/getSongList'
const data = Object.assign({}, commonParams, {
disstid,
type: 1,
json: 1,
utf8: 1,
onlysong: 0,
platform: 'yqq',
hostUin: 0,
needNewCode: 0,
g_tk: 67232076
})
return axios.get(url, {
params: data
}).then(res => {
return Promise.resolve(res.data)
})
}
就可以获取到了,songlist是放在获取的结果中的
res.cdlist[0].songlist