一、问题描述
当使用跨域jsonp接口时。referer属性是前台接口告诉服务器该接口的域名,而后台可以对应设置请求头referer从而对接口进行限制访问。
当服务端对referer进行 验证后,非referer指定域名的请求访问该接口时,服务端会返回500。访问失败。
二、解决
由于在前端发送请求时无法直接修改referer值,故需要利用vue项目中的server进行请求转发,并在转发的同时设置referer进行伪造,冒充指定的域名欺骗服务端。
三、实践
在vue-cli 3.0-版本中,在config目录,提供了dev-server 和 dev-client的配置,可在dev-server.js文件中进行配置
//引包
var app = express()
var apiRoutes = express.Router()
//配置
apiRoutes.get('/getDiscList', function (req, res) {
var url = 'xxxxx' //接口地址
axios.get(url, {
headers: {
referer: 'xxxx/', //指定referer
host: 'xxxx' //指定主机名
},
params: req.query
}).then((response) => {
res.json(response.data)
}).catch((e) => {
console.log(e)
})
})
app.use('/api', apiRoutes)
而在vue-cli 3.0+中对配置文件进行了简化,去除了dev-server配置文件。
需要在 webpack.dev.conf.js
中进行配置
// 引包
var express = require('express')
var axios = require('axios')
var app = express()
var apiRoutes = express.Router()
// 配置
devServer: {
//添加一个before方法
before(apiRoutes){
apiRoutes.get('/api/xxxx',(req,res)=>{ //将对本api请求进行转发
const url = 'xxx'; //转发的目的url
axios.get(url, {
headers: {
referer: 'https://xxx',
host: 'xxx'
},
params: req.query //请求的query
}).then((response) => {
//response是api地址返回的,数据在data里。
res.json(response.data)
}).catch((e) => {
console.log(e);
})
});
app.use('/api', apiRoutes);
}
}
此处在项目实践中出现了代理失败的问题
此处出现了404,经排查,问题在于配置中的
/api/xxx
缺少了开头的斜杠`/,导致无法捕获到浏览器发出的本地请求,也就没有执行下面对headers进行配置后使用axios发送jsonp请求的逻辑。整个代理并没有触发,并且本地的接口也并不存在,所以404。
网友评论