共计 2155 个字符,预计需要花费 6 分钟才能阅读完成。
使用 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 错误
- 使用代理服务端的方法接口上面的问题
- 代理服务端的原理是:
- 在 webpack-dev-conf.js 中给 express 服务器一个请求 express 服务器端地址‘/api/getDiscList’,这样前端请求的时候不用去请求真正的 qq 接口,而是去请求 express 服务器,当前端去发送一个请求 express 服务器端地址【/api/getDiscList】时,本地的 local server 就去请求相应的真正的 qq 接口【https://c.y.qq.com/splcloud/f…】。
- 在 webpack-dev-conf.js 进行配置,通过 req 从浏览器端发过来的一堆参数 (platform,sin,ein 等) 透传给 qq 的服务端,通过 axios 请求 QQ 服务端,当请求响应的时候,qq 服务端的响应数据,再通过 res 将响应数据输出到浏览器端。
- recommend.js 中获取数据,请求的是本地 express 服务器的 api 数据(ajax 请求),(本地 express 的数据是上边通过 axios 获得的)不是 Jsonp 数据了,返回的是 axios 的数据
正文完