Uncaught ReferenceError: jp2 is not defined,用jsonp抓取qq音樂總是說回撥函式沒有定義
阿新 • • 發佈:2018-12-24
問題如下參考連結: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