在api中写一个song.js用于抓取歌词数据。
通过查看qq音乐的js请求,可以得到歌词数据的url,由于请求头header中需要referer为为'https://c.y.qq.com/',host为'c.y.qq.com'。这时就不能直接使用jsonp,需要在服务端写一个方法来改变请求头。
1.在dev-server.js中定义方法改变请求头
var apiRoutes = express.Router() //得到Router
apiRoutes.get('/getLyric', function(req, res) {
var url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg'
axios.get(url, {
headers: {
referer: 'https://c.y.qq.com/',
host: 'c.y.qq.com'
},
arams: req.query
}).then((response) => {
// 这里的response.data为字符串,需要进行处理,得到json
var ret = response.data
// ret: "MusicJsonCallback({\"retcode\":0,\"code\":0,\"subcode\":0,\"lyric\":\"W3R......T\",\"trans\":\"\"})"
if (typeof ret === 'string') {
var reg = /^\w+\(({[^()]+})\)$/
var matches = ret.match(reg)
if (matches) {
ret = JSON.parse(matches[1])
}
}
// res.json()发送一个JSON应答,参数必须为json
res.json(ret)
}).catch((e) => {
console.log(e)
})
})
app.use('/api', apiRoutes)
2.在src中的api下写song.js,访问dev-server.js中的getLyric方法,抓取数据
使用axios.get()方法进行访问,get方法有两个参数:
① url //这里的url为dev-server.js中的getLyric,即‘api/getLyric’
② params //抓取歌词数据需要的参数
axios支持Promise的api,可以使用then来定义回调函数,song.js中的返回如下:
return axios.get(url, {
params: data
}).then((response) => {
// response的结构包括:config,headers,request,data,status,statusText
// 其中response.data为dev-server.js中res.json发送的json数据
return Promise.resolve(response.data)
})
这样得到就抓取到了歌词数据,但是我们要在项目中使用它,则需要将它加入到song类中
3.在song的class中,定义getLyric方法
getLyric() {
return new Promise((resolve, reject) => {
getLyric(this.mid).then((res) => {
if (res.retcode === ERR_OK) {
this.lyric = res.lyric
console.log(this.lyric)
}
})
})
}
在getLyric方法中,调用了api/song.js中的getLyric方法,该方法返回 Promise.resovle(data),其中Promise.resolve()方法的作用是将现有的对象转为Promise对象, 当参数不是具有then方法的对象,或者根本不是对象时,Promise.resolve方法返回一个新的Promise对象,状态为resolved
因此,在class Song中new Promise中,getLyric方法返回的promise对象状态为resolved,触发then,将lyric赋值给Song对象的lyric属性