手把手教你用原生js封装jsonp去抓取qq音乐的api

869 阅读1分钟

// jsonp.js
export default (options) => {  
    if (!options || !options.url) return  
    let id = 0  // 用于生成callback函数名  
    let header = document.querySelector('head')  
    let script = document.createElement('script')  
    let url = options.url  let data = options.data || {}  
    let callback = options.callback  let fnName = "jsonp" + id++  

    // 添加回调函数名  
    data[options.param] = fnName  
    // 拼接url  
    let params = []  
    for (let key in data) {    
        if(data[key]) {      
            params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)   
        }  
    }  
    url += url.indexOf('?') > 0 ? '&' : '?'  
    url += params.join('&')  
    script.src = url  
    
    // 将传递的是一个匿名的回调函数暴露为一个全局方法  
    window[fnName] = function(res) {    
        callback && callback('', res)    
        header.removeChild(script)    
        delete window[fnName]  
    }  
    // 出错处理  
    script.onerror = function(){    
        callback && callback({error: 'error'})    
        header.removeChild(script)    
        window[fnName] && delete window[fnName]  
    }  
    script.type = 'text/javascript'  
    header.appendChild(script)
}

// 用promise封装使用jsonp
// promise.js
import jsonp from "./jsonp";

export default (url, data, opt) => {
      return new Promise((resolve, reject) => {
        jsonp({
          url: url,
          data: data,
          param: opt.param
          callback: function (err, res){
            if (!err) {
              resolve(res)
            } else {
              reject(err)
            }
          }
        }, opt)
  })
}

// 写qq音乐的接口
// api.js

import promise from "./promise"

export default () => {
  // qq音乐的推荐页面对应的接口
  let url = 'https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg'
  // 可以去qq音乐网页打开network看对应的参数
  let data = {
    g_tk: 1928093487,
    inCharset: 'utf-8',
    outCharset: 'utf-8',
    notice: 0,
    format: 'jsonp',
    platform: 'h5',
    uin: 0,
    needNewCode: 1
  }
  // jsonp请求时与后台协商的callback名,qq音乐是'jsonpCallback' 
  let opt = {
      param: 'jsonpCallback'
  }

  return promise(url, data, opt)
}

// 测试
// test.js

import music from "./api"

music().then(res => {
  console.log(res)
})