使用jsonp去抓取数据的时候,数据的接口有host和referer的显示,我们的api请求被拒绝(500错误),必须要修改header,但是前端不能直接修改request header,我们采取后端接口代理的方法去解决使用express,这样前端去请求接口的时候不是直接请求服务器的url,而是请求我们自己的server端,让local server再去请求QQ服务端

使用express启动代理服务器

原理:在封装的请求数据函数getDiscList中不是直接请求url,而是请求express服务器端地址,再让我们的local server去请求服务端,使用nodejs请求服务器端,用到一个axios库,在浏览器端发送的是xmlhttprequest请求,在nodejs中发送的是http请求。

axios请求服务器,在webpack-dev-conf.js中做如下配置

const express = require('express')
const axios = require('axios')
const app = express()
var apiRoutes = express.Router()
app.use('/api', apiRoutes)
在devServer{}中添加

before(app) {

  app.get('/api/getDiscList', (req, res) => {
    var url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
    axios.get(url, {
      headers: {
        referer: 'https://c.y.qq.com/',
        host: 'c.y.qq.com'
      },
      params: req.query // 通过req从浏览器端发过来的一堆参数(platform,sin,ein等)透传给qq的服务端
    }).then((response)=>{ // qq服务端的响应数据,再通过res将响应数据输出到浏览器端
      res.json(response.data)
    }).catch((error)=>{
      console.log(error)
    })
  })
}

之后,回到recommend.js中获取数据,请求的是本地express服务器的api数据(ajax请求),(本地express的数据是上边通过axios获得的)不是Jsonp数据了,返回的是axios的数据

export function getDiscList() {
  //调用这个方法时请求url时请求的不是QQ服务端,而是自己的server端,请求的是请求express服务器端地     址'/api/getDiscList'
  //而,我们去请求api时,在webpack.dev.conf.js中,让local server再去请求QQ服务端
  //这样做的结果就是,不是前端直接去请求QQ服务端,而是通过中介自己的local server去请求QQ服务端
  
  // const url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
  const url = '/api/getDiscList' //此时这个url并不是我们通常意义上的接口而是express服务器端地址
  const data = Object.assign({}, commonParams, {
    platform: 'yqq',
    hostUin: 0,
    sin: 0,
    ein: 29,
    sortId: 5,
    needNewCode: 0,
    categoryId: 10000000,
    rnd: Math.random(),
    format: 'json' // 使用的时axios,所以format使用的是json,不是jsonp
  })
  return axios.get(url, {
    params: data
  }).then((res) => {
    return Promise.resolve(res.data)
  })
}

总结整个过程

  • 在用jsonp请求QQ接口的时候,由于host和referer是QQ服务端自己的,我们的请求会出现500错误
  • 使用代理服务端的方法接口上面的问题
  • 代理服务端的原理是:
  1. 在webpack-dev-conf.js中给express服务器一个请求express服务器端地址‘/api/getDiscList’,这样前端请求的时候不用去请求真正的qq接口,而是去请求express服务器,当前端去发送一个请求express服务器端地址【/api/getDiscList】时,本地的local server就去请求相应的真正的qq接口【https://c.y.qq.com/splcloud/f...】。
  2. 在webpack-dev-conf.js进行配置,通过req从浏览器端发过来的一堆参数(platform,sin,ein等)透传给qq的服务端,通过axios请求QQ服务端,当请求响应的时候, qq服务端的响应数据,再通过res将响应数据输出到浏览器端。
  3. recommend.js中获取数据,请求的是本地express服务器的api数据(ajax请求),(本地express的数据是上边通过axios获得的)不是Jsonp数据了,返回的是axios的数据

素素
37 声望0 粉丝

引用和评论

0 条评论