用jsonp抓取qq音乐总是说回调函数没有定义

用jsonp抓取qq音乐总是说回调函数没有定义,
clipboard.png

我的要实现时候的步骤
1。第一步
clipboard.png

我要实现的目的

clipboard.png

问题:如题

我的部分代码:

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...

阅读 11.2k
11 个回答

确实不能通过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

解决问题了,服务端拒绝了自定义名称的回调函数,服务上规定了固定回调函数名,
方案1.返回它规定的名字。
方案2.基于jsonp这个第三方库,设置自定义的cbname

请问// 热门歌单详情歌曲
export function getHotSongList(disstid) {
const url = 'https://c.y.qq.com/qzone/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, 'playlistinfoCallback')
}
这样可以吗。要怎么弄啊。

用了上边提到的修改jsonpCallback方法都没成功
仔细看提示: "invalid referer" 无效的refer,
跟前边视频讲的获取getDiscList方法一样, 需要用axios绕过

最新的 referer: 'https://y.qq.com/'

代码:

//recommend.js
export function getSongList (disstid) {
    const url = '/getSongList'
    const data = Object.assign({}, commonParams, {
        format: 'json',
        needNewCode: 1,
        disstid: disstid,
        type: 1,
        json: 1,
        utf8: 1,
        onlysong: 0,
        g_tk: 1800233000,
        platform: 'yqq',
        needNewCode: 0,
        onlysong: 0,
        notice: 0
    })
    return axios.get(url, {
        params: data
    }).then((res) => {
        return Promise.resolve(res.data)
    })
}

//webpack.dev.conf.js
    app.get('/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) => {
        res.json(response.data)
      }).catch((e) => {
        console.log(e)
      })
    })

你有定义过jp1函数么?没有的话是怎么成功的呢?
建议看看jsonp的原理

新手上路,请多包涵

你好,想问返回错误解决了吗

你好,我的为什么报的是冒号错误。
fcg_yqqhomepagerecommend.fcg?g_tk=5381&inCharset=utf-8&outChart=utf-8&notice=0&format=jsonp&platform=h5&uin=0&needNewCode=1&callback=%3A:1

Uncaught SyntaxError: Unexpected token :

clipboard.png

clipboard.png

如图,我的参数都是对的,也都是jsonp这个库,为什么还会返回无法调用的提示啊

新手上路,请多包涵

你好,我的数据也是出现了
{code: 0, subcode: 1, msg: "invalid referer"}
code:0
msg:"invalid referer"
subcode:1
__proto__:Object

新手上路,请多包涵

我也刚碰到这个问题,楼主说的服务端拒绝了自定义名称的回调函数给了我启发啊。(我抓的QQ空间音乐)
export const options = {
param: 'jsonpCallback',
prefix: 'JsonCallback' //要加上这个
}
还要修改jsonp模块里的index.js第50行
var id = opts.name || prefix; // 原来有个count++ 自增变量,删掉就好,因为这个东西就会让JsonCallback变成JsonCallback0,服务器就不认识了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题