在api中寫一個song.js用于抓取歌詞數(shù)據(jù)。
通過查看qq音樂的js請求,可以得到歌詞數(shù)據(jù)的url,由于請求頭header中需要referer為為'https://c.y.qq.com/',host為'c.y.qq.com'。這時就不能直接使用jsonp,需要在服務(wù)端寫一個方法來改變請求頭。
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為字符串,需要進行處理,得到j(luò)son
? ? ? ? ? ? ?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()發(fā)送一個JSON應(yīng)答,參數(shù)必須為json
? ? ? ? ? ?res.json(ret)
? ? ?}).catch((e) => {
? ? ? ? ? ?console.log(e)
? ? ?})
})
app.use('/api', apiRoutes)
2.在src中的api下寫song.js,訪問dev-server.js中的getLyric方法,抓取數(shù)據(jù)
使用axios.get()方法進行訪問,get方法有兩個參數(shù):
①?url? ?//這里的url為dev-server.js中的getLyric,即‘a(chǎn)pi/getLyric’
②?params //抓取歌詞數(shù)據(jù)需要的參數(shù)
axios支持Promise的api,可以使用then來定義回調(diào)函數(shù),song.js中的返回如下:
return axios.get(url, {
? ? ? ? ? params: data
? ? ?}).then((response) => {
? ? ? ? ?// response的結(jié)構(gòu)包括:config,headers,request,data,status,statusText
? ? ? ? //?其中response.data為dev-server.js中res.json發(fā)送的json數(shù)據(jù)
? ? ? ? ?return Promise.resolve(response.data)
})
這樣得到就抓取到了歌詞數(shù)據(jù),但是我們要在項目中使用它,則需要將它加入到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方法中,調(diào)用了api/song.js中的getLyric方法,該方法返回 Promise.resovle(data),其中Promise.resolve()方法的作用是將現(xiàn)有的對象轉(zhuǎn)為Promise對象,?當參數(shù)不是具有then方法的對象,或者根本不是對象時,Promise.resolve方法返回一個新的Promise對象,狀態(tài)為resolved
因此,在class Song中new Promise中,getLyric方法返回的promise對象狀態(tài)為resolved,觸發(fā)then,將lyric賦值給Song對象的lyric屬性