关于http-proxy
使用npm构建前端项目的话应该很熟悉http-proxy这个模块了,它能代理HTTP请求,有了它我们真正实现前后端开发完全分离,甚至部分资源也能代理到相应资源。
如果用过VPN的童鞋就更容易理解了,有时候要看点朝内看不到的内容就得先把请求发到朝外某台代理服务器上,然后那代理服务器再请求相应的资源并把获取到的请求结果返回给客户端。
http-proxy的使用非常简单,https://www.npmjs.com/package/http-proxy 详细用法看这里
起因因为一个小问题
因为遇到了一个小问题,折腾了半天最后搞定后才发现http-proxy玩玩全全就是傻瓜式的转发,后来发现这样设计也挺好。
我当时的开发环境为本地静态开发localhost:3000
,需要代理的机器假设为server.com
然后我的设置如下:
httpProxy.createProxyServer({
target: 'http://server.com'
});
function proxyMiddleware (req, res, next) {
if (/\/api\/.*$/.test(req.url)) {
proxy.web(req, res);
} else {
next();
}
}
所有的API都请求都走proxy了,但返回的不对,都是404,服务器上tail webserver access.log
居然没有捕获到,这让我感觉很诡异。REST Api调试工具里访问Server API也没问题。
发现问题所在
最后我监听服务器所有http请求,居然发现了一个问题。
请求过来的host为localhost,发现问题了。但是奇怪了,为什么host都是localhost呢?
我认为可能跟我的本地开发localhost:3000
有关,于是我改成这样
hosts
127.0.0.1 server.com
修改http-proxy配置
httpProxy.createProxyServer({
target: 'http://192.168.1.85' // 服务器IP
});
然后打开浏览器,使用server.com:3000
域名访问,重新测试API代理,成功了,这回服务器上抓到的head里host都是server.com
。
解决问题
找到问题了,但总感觉这样不太友好,于是我把系统host文件的127.0.0.1 server.com
删除了,恢复server.com的真实访问,然后在http-proxy中改成这样
httpProxy.createProxyServer({
target: 'http://192.168.1.85' // 服务器IP
});
function proxyMiddleware (req, res, next) {
if (/\/api\/.*$/.test(req.url)) {
proxy.headers.host = 'server.com'; // 这里修改代理请求服务器的host名称
proxy.web(req, res);
} else {
next();
}
}
最后重启本地前端项目,loalhost:3000/api/xxxx
请求服务器资源,代理到服务器后所有host都不是localhost而是在http-proxy配置中的server.com了。
当然,如果server上没有配置虚拟主机,ip/域名访问都是同一个程序的话,就不会存在以上问题