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

相关文章
相关标签/搜索