vue慕课网音乐项目手记:32-如何获取歌词的数据,并解析jsonp的格式为json的格式

时间:2022-12-18 09:29:03

首先:在qq音乐的官网,能看到如下的歌词数据

vue慕课网音乐项目手记:32-如何获取歌词的数据,并解析jsonp的格式为json的格式

这是一个jsonp的数据,但是官方对它做了一些加密,所以还是要通过node去强制改变请求头。

新建一个song.js

import { commonParams } from './config'
import axios from 'axios'

export function getLyric (mid) {
  const url = '/api/lyric'

  const data = Object.assign({}, commonParams, {
    g_tk: 1930664565,
    pcachetime: +new Date(),
    这里是一段时间戳
    hostUin: 0,
    format: 'json',
    因为是请求本地的接口,所以format是json
    platform: 'yqq',
    needNewCode: 0,
    songmid: mid
  })
  return axios.get(url, {
    params: data
  }).then((res) => {
    return Promise.resolve(res.data)
  })
}      
然后在node中去强行更改请求头
app.get('/api/lyric', function (req, res) {
        var url = 'https://szc.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.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)
        })
      })

然后获取数据的方法封装到class类中:

getLyric () {
    getLyric(this.mid).then((res) => {
      if (res.code === ERR_OK) {
        this.lyric = res.lyric
        console.log(this.lyric)
      }
    })
  }

因为请求的仍然是一个jsonp,所以要在后端做一点小小的处理:

 var ret = response.data
          if (typeof ret === 'string') {
            var reg = /^\w+\(({[^()]+})\)$/
            // 以单词a-z,A-Z开头,一个或多个
            // \(\)转义括号以()开头结尾
            // ()是用来分组
            // 【^()】不以左括号/右括号的字符+多个
            // {}大括号也要匹配到
            var matches = ret.match(reg)
            if (matches) {
              ret = JSON.parse(matches[1])
            // 对匹配到的分组的内容进行转换
            }
          }
以上是通过正则表达式把获取到的jsonp文件转换成json格式