记一次http-proxy-middleware的错误使用
2018-04-25 本文已影响4人
天驱丶
最近新接了一个项目,需要在启动时选择代理到不同的后端地址,我就想到用 inquirer 做命令选择
- inquirer 引用代码
// inquirer 版本 5.2.0
function ask() {
var proxys = require('./serverProvider')
return inquirer.prompt([
{name: 'prefix', type: 'input', message: '请输入prefix(如果有)'},
{name: 'target', type: 'list', message: '请选择代理的地址', choices: Object.values(proxys)}
])
.then(answers => {
app.use(proxyMiddleware(answers['prefix'], {
target: answers['target'],
changeOrigin: true
}))
resolve()
})
.catch(e => {
reject(e)
})
}
- serverProvider 文件
module.exports = {
provider1: '172.27.49.11:8081', // 小明
provider2: '172.27.49.10:8081', // 小红
}
执行 npm run dev
后,报错:
解决问题
- 看到所属包是
requires-port
, 调用该包的库是http-proxy-middleware
, 看到该包版本为0.17.3,就想着是不是版本太低的 bug,逐使用npm update | grep http-proxy-middleware
,发现最新也就0.17.4,基本可排除版本问题。 - 那就看该库哪里报错吧,根据提示找到
node_models/requires-port/index.js
13行
module.exports = function required(port, protocol) {
protocol = protocol.split(':')[0];
...
}
可以看到是传进来的protocol为空,所以执行 split 操作时报错(其实细心点这时已经可以知道错误在哪了)
然后在node_models全局搜'requires-port'(或者看报错第二行),定位到node_models/http-proxy/lib/http-proxy/common.js 109行
if (options.changeOrigin) {
outgoing.headers.host =
required(outgoing.port, options[forward || 'target'].protocol) && !hasPort(outgoing.host)
? outgoing.host + ':' + outgoing.port
: outgoing.host;
}
是options[forward || 'target'].protocol为undefined,所以导致调用 requires-port 出错,打印出 options 后发现是 target: xxxx
,是个 String 类型,之后将这个改为含有protocol的对象就正常执行了。
后续
发现之前项目也是target为String的,但没有报错,对比后发现原来是写的后端地址没有写上协议(心酸~~),补充后String类型也是可以的。
还有一个关于inquirer的补充吧,因为后端地址现在是对象的形式,只能获取value,但不能在选择的时候就与是哪个同事的地址匹配,所以改成Map形式
// 更改后的serverProvider
const map = new Map()
map.set('小明', '172.27.49.11:8081')
map.set('小红', '172.27.49.10:8081')
// TODO 可以做成一个类,添加validate方法校验
module.exports = Array.from(map)
// 修改引用代码
function ask() {
var proxys = require('./serverProvider')
return inquirer.prompt([
{name: 'prefix', type: 'input', message: '请输入prefix(如果有)'},
{name: 'target', type: 'list', message: '请选择代理的地址', choices: proxys.map(it => String(it))}
])
.then(answers => {
app.use(proxyMiddleware(answers['prefix'], {
target: answers['target'].split(',')[1],
changeOrigin: true
}))
})
}
总结
这个错误其实是一个低级错误,不应该犯的,将这篇文章写出来是为了分享我的问题解决方式,如有哪些地方可以改进的也可以留下评论。