vue2.x 經過後端接口代理,獲取qq音樂api的數據

部分qq音樂的api接口不能直接經過jsonp訪問,須要經過官方的代理才能獲取,如:歌詞,推薦歌單等,本例是獲取歌詞node

  1. webpack.dev.conf.js中建立接口: // 開頭調用:
var express = require('express')
var axios = require('axios')
var app = express()
var apiRoutes = express.Router()
app.use('/api', apiRoutes)
 
// devServer的最後添加:
    before(app) {
      // 而後在node中去強行更改請求頭
      // 後端代理請求api
      app.get('/api/lyric', 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'
          },
          params: req.query
        }).then((response) => {
          res.json(response.data)
        }).catch((e) => {
          console.log(e)
        })
      })
    }
複製代碼

2.(這是一個jsonp的數據,可是官方對它作了一些加密,因此仍是要經過node去強制改變請求頭。)在 api的song.js文件中,將url換成步驟1中自定義的接口,經過axios獲取返回數據webpack

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

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

  const data = Object.assign({}, commonParams, {
    songmid: mid,
    pcachetime: +new Date(),
    g_tk: 1907351394,
    loginUin: 1575645784,
    hostUin: 0,
    platform: 'yqq',
    needNewCode: 0,
    format: 'json'
  })

  return axios.get(url, {
    params: data
  }).then((res) => {
    return Promise.resolve(res.data)
  })
}
複製代碼
  1. (而後獲取數據的方法封裝到class類中)歌詞能夠看作是song的一個屬性,爲Song類擴展一個方法.在js的song.js裏
import {getLyric} from 'api/song'
import {ERR_OK} from 'api/config'

export default class Song {
  constructor({id, mid, singer, name, album, duration, image, url}) {
    this.id = id
    this.mid = mid
    this.singer = singer
    this.name = name
    this.album = album
    this.duration = duration
    this.image = image
    this.url = url
  }
  // 歌詞能夠看作是song的一個屬性,爲Song類擴展一個方法
  // 而後獲取數據的方法封裝到class類中:
  getLyric() {
    getLyric(this.mid).then((res) => {
      if (res.retcode === ERR_OK) {
        this.lyric = res.lyric
        console.log(this.lyric)
      }
    })
  }
}
複製代碼
  1. 組件中經過js的song.js文件中的方法獲取數據
watch: {
    // 播放歌曲,調用dom的play()方法
    currentSong(newSong, oldSong) {
      if (newSong.id === oldSong.id) {
        return
      }
      this.$nextTick(() => {
        this.$refs.audio.play()
        this.currentSong.getLyric()
      })
    }
  }
複製代碼

結果返回jsonp數據:ios

五、由於請求的仍然是一個jsonp,因此要在後端作一點小小的處理:

var ret = response.data
          if (typeof ret === 'string') {
            // 捕獲jsonp的正則
            var reg = /^\w+\(({[^()]+})\)$/
            // 以單詞a-z,A-Z開頭,一個或多個
            // \(\)轉義括號以()開頭結尾
            // ()是用來分組
            // [^()]不以左括號/右括號的字符+多個
            // {}大括號也要匹配到
            var matches = ret.match(reg)
            if (matches) {
              ret = JSON.parse(matches[1])
            }
          }
          // 經過json方式輸出出去
          res.json(ret)
複製代碼

結果返回json數據:web

相關文章
相關標籤/搜索