webpack中使用反向代理或者后端代理

2018-08-04  本文已影响27人  苏阿柒

前两天做了一个小样,做一个请求去获取某音乐网站的数据,中间碰到了一些问题,这里简单的记录一下
完整的请求地址:https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg
相关数据如下:

qq音乐.jpg
首先一个,本地webpack服务去获取该音乐网站的数据是跨域的,面对跨域我们一般的情况下都会想到用jsonp去做请求数据
正常情况下,我们只要在config/index.js里的proxyTable里添加跨域配置,就可以在组件中像一般请求那样去用了,就像下面这样
config/index.js:
proxyTable: {
      '/api': {
        target: 'https://c.y.qq.com/',//设置调用的接口域名和端口号
        changeOrigin: true,
        pathRewrite: {
          //关于这个属性,网上有很多解释,这里就不详细说明了
        }
      }
    }

在组件中使用

axios.get('/api/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg',data)
    .then((res) => {
    console.log(res)
    })
    .catch((err) => {
        console.log(err);
    })

但是这里涉及到一个问题,某些网站有一些数据不是公开的,有一些请求链接会有特别的请求头数据,类似下面这种

referer: 'https://c.y.qq.com/',
host: 'c.y.qq.com'

而根据ECMA中关于jsonp的规定,为了保护跨域安全,jsonp的请求头中referer和host是不可更改的,所以我们用正常的跨域请求去请求这个地址的话,一般不会报错,但是请求过来的数据是不对的
那在这种情况下,我们就需要用到后端代理了,这里是在webpack.dev.conf.js中做一个后端代理,让这个代理去请求我们想要的数据
在webpack.dev.conf.js添加如下配置:

const express = require('express')
const axios = require('axios')
const app = express()
let apiRoutes = express.Router()
app.use('/api', apiRoutes)

并在devServer中添加before方法

before(app) {
      app.get('/api/getDiscList', function (req, res) {
        let 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
        }).then((response) => {
          res.json(response.data)
        }).catch((e) => {
          console.log(e)
        })
      })

配置请求方法

getDiscList() {
  const url = '/api/getDiscList'
  const commonParams = {
    g_tk: 1928093487,
    inCharset: 'utf-8',
    outCharset: 'utf-8',
    notice: 0,
    format: 'jsonp'
  }
  const data = Object.assign({}, commonParams, {
    platform: 'yqq',
    hostUin: 0,
    sin: 0,
    ein: 29,
    sortId: 5,
    needNewCode: 0,
    categoryId: 10000000,
    rnd: Math.random(),
    format: 'json'
  })

  return axios.get(url, {
    params: data
  }).then((res) => {
    return Promise.resolve(res.data)
  })
}

在组件中调用

created() {
      this._getDiscList()
    },
    methods: {
       _getDiscList() {
        getDiscList().then((res) => {
          if (res.code === 0) {
            this.discList = res.data.list
          }
        })
      }
}

以上都是在开发环境中进行

上一篇下一篇

猜你喜欢

热点阅读