导语

最近有个需求,需要对业务管理后台的操作记录进行上报。一般这种上报需求都是又后台同学来做比较合适的。但是因为后台人力的原因。这个工作落到了我这个小前端的头上。这里记录下做这个需求踩的一些坑。

一、实现反向代理

做为一个前端工程师,写代理脚本第一选择肯定是node。不过在此之前,要把请求代理到机器A上面的node服务上面。这里使用了tnginx。在nginx.config文件里面添加以下配置并重启。把cgi域名下的请求,代理到机器上面的8000端口node 服务。

server{
listen 80;
server_name cgi.qqcomic.oa.com admin.cgi.qqcomic.oa.com;
access_log /usr/local/services/tnginx_1_0_0-1.0/access.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
}
}

然后使用node的http-proxy模块,起一个代理server,就像这样。

    var httpProxy = require('http-proxy');
var http = require('http')
http.createServer(function(req, res) {
proxy.web(req, res, { target: http://10.213.167.135});
}).listen(8000);

本机使用fiddler 代理cgi域名到测试机器A的ip,刷新一下,成功访问到cgi内容。(ps: 注意idc机器是没有dns解析服务的,这里需要在 /etc/hosts文件上面添加相关域名的ip地址)

二、获取请求的相关数据

成功实现请求代理是一个好的开始。现在,需要开始搞点事情了。首先,我们需要获取请求的参数,这些参数可能是在url里面,也可能是在POST实体里面。url里面的参数很容易拿到,只需要读取req对象的url就能获取。POST实体里面的数据获取比较麻烦,因为POST请求的种类比较多,手动解析比较麻烦。这里使用了formidable模块来解析。然后把解析完成的结果挂载在req对象上面,方便后面获取。

  function getBody(request){
var formidable = require('formidable');
var form = new formidable.IncomingForm(),fields = {};
//..巴拉巴拉,解析出参数,挂载在request对象上面
}

除了请求的参数,我们还需要获取cgi回包的数据,这样才能判断这个请求是不是有效的。获取回包数据,可以在res对象上面监听data事件,拼接回包数据。类似这样封装一个方法:

    function getResRawData(res,callback){
var resData = ''
res.on('data', function(chunk){
resData = resData + chunk.toString();
});
res.on('end', function(chunk){
try {
resData = JSON.parse(resData);
callback(null,resData)
}catch (e){
callback(e)
}
});
res.on('error', function(err){
callback(err)
});
}

比较坑一点的是,回包可能会被gzip压缩,这样我们上面代码得到的会是乱码。因此处理回包的时候,要判断回包的content-encoding是不是gzip,如果是gzip的话,需要使用node的zlib模块进行解压。

三、进行数据上报

获取了请求的参数和回包内容,我们就可以进行数据上报了,上报的时机应该是在代理请求回包之后。http-proxy模块提供了proxyRes事件给我们监听,我们可以在这个事件的回调函数里面,获取回包的内容,并调用上报方法,使用node的request模块进行数据上报。类似这样:

    var request = require('request');
proxy.on('proxyRes', function (proxyRes,req,res) {
//获取回包内容
getResRawData(proxyRes,function(err,data){
//发起请求上报
request.post(data, function(err,httpResponse,body){
console.log(body)
})
})
});

四、划分路由模块

系统的cgi可能不只是一个命令,可能不只是一种回包格式。所以我们需要添加一个路由模块,把不同请求,映射到对应的处理器上面。可以比较简单的根据正则匹配url,返回不同的模块字符串,然后在代理请求回包后,根据模块字符串require这些模块去处理对应的请求。类似这样:

  http.createServer(function(req, res) {
var route = router(req);//根据请求url,返回对应的模块字符串
//根据请求,获取处理请求的模块
var target = (route && route.target) || null;
if(!target){
res.end('bad request')
}else{
//注入配置到req对象里面,后面会用到
req.routerConfig = route
proxy.web(req, res, { target: target});
}
}).listen(8000); proxy.on('proxyRes', function (proxyRes,req,res) {
//获取回包内容
getResRawData(proxyRes,function(err,data){
//根据路由配置,加载对应的处理器去处理请求
if(req.routerConfig && req.routerConfig.handle){
action = require(req.routerConfig.handle);
action.handle(req,data)
}
})
});

附:系统设计流程图

五、小结

有了node之后,前端有了更大的舞台,可以帮助解决一些后台的工作。这次的需求只是一个小小的应该例子,后续我们还可以在这个proxy server的基础上,添加白名单做权限限制,限制某些rtx用户只能操作固定的cgi。

此文已由作者授权腾讯云技术社区发布,转载请注明文章出处

搞点事情,使用node搭建反向代理的更多相关文章

  1. ECS上nginx搭建反向代理通过内网访问阿里云OSS服务

    对于付不起钱的小伙计,为了给公司省钱,想尽一切招数.今天就来分享一个使用阿里云OSS存储搭配CDN使用的网站服务器部署方法. 简介 阿里云OSS 阿里云提供的一种文件存储方案,和我们以前接触的百度云B ...

  2. 一文教您如何通过 Docker 搭建反向代理 Ngnix,并配置 Https SSL 证书

    欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注附送 100G 海量学习资源哟!! 个人网站: https://www.exception.site/docker/h ...

  3. centos7安装nginx,以及使用node测试反向代理

    1.添加nginx的安装源 vi /etc/yum.repos.d/nginx.repo 2.输入下面内容,并保存退出 [nginx] name=nginx repo baseurl=http://n ...

  4. 解决异地服务器接口访问跨域,node构建反向代理

    跨域对于前端来说是一个老大难的问题,许多方法如jsonp.document.domain + iframe...都有或多或少的问题,一个最佳实践就是通过服务器nginx做反向代理,但奈何不懂相关知识, ...

  5. Nginx之搭建反向代理实现tomcat分布式集群

    参考博文: Nginx反向代理实现Tomcat分布式集群 1. jdk 安装 jdk 下载网址: http://www.oracle.com/technetwork/java/javase/downl ...

  6. CentOS7下Nginx搭建反向代理,并使用redis保存session

    1.启动两个tomcat,端口分别为8080,8081 2.配置nginx,vim /usr/local/nginx/conf/nginx.conf 添加如下配置: 3.启动nginx或热加载 启动: ...

  7. 安装Nginx并为node.js设置反向代理

    最近看了反向代理和正向代理的东西,想到自己的node.js服务器是运行在3333端口的,也没有为他设置反向代理,node.js项目的一些静态文件是完全可以部署在Nginx上,以减少对node.js的请 ...

  8. CentOS7安装部署squid服务(透明代理+反向代理)

    一.squid服务介绍 Squid是一个高性能的代理缓存服务器,Squid支持FTP.gopher.HTTPS和HTTP协议.和一般的代理缓存软件不同,Squid用一个单独的.非模块化的.I/O驱动的 ...

  9. Nginx之最简单的反向代理机制分析

    注:当前分析基于 Nginx之搭建反向代理实现tomcat分布式集群 的配置. 1. 用到的指令 下面介绍在上面的配置中用到的指令. upstream 指令 语法:upstream name { .. ...

随机推荐

  1. manacher 算法 这个人确实写得太好了;

    O(n)回文子串(Manacher)算法 资料来源网络 参见:http://www.felix021.com/blog/read.php?2040 问题描述: 输入一个字符串,求出其中最大的回文子串. ...

  2. Linux shell字符串截取与拼接

    一 Linux 的字符串截取很有用.有八种方法. 假设有变量 var=http://www.linuxidc.com/123.htm 1  # 号截取,删除左边字符,保留右边字符. echo ${va ...

  3. BZOJ2724 蒲公英 【分块】

    BZOJ2724 蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被 ...

  4. java 并发时使用条件变量--Condition

    lock--unlock的方式在实际中使用较少,一般使用synchronized获取对象的内部锁替代,但是lock--unlock对了解synchronized有很大的帮助. 创建一个bank对象用于 ...

  5. jdk、jre、JVM的简单区别与联系

    2015-10-20 23:08:52 (1)jdk Java development toolkit(开发工具包),JDK是整个JAVA的核心,包括了Java运行环境jre(Java Runtime ...

  6. FastAdmin 中使用 Oder by if 强行将某一类放到前面

    FastAdmin 中使用 Oder by if 强行将某一类放到前面 问题来源社区问题 1,查了一些资料2,做了测试. 如下表,我想把 snake 单独放到开始. 可以使用以下查询语句(默认为 AS ...

  7. 记一次 FastAdmin CMS 内容提示空的问题

    记一次 FastAdmin CMS 内容提示空的问题 有小伙伴反馈 FastAdmin CMS 安装后出现内容有文字,但提示错误 的问题. 我在本地重新安装测试并没有发现这个问题,一切正常,编辑器也可 ...

  8. JDBC 流程

    转载地址:https://blog.csdn.net/suwu150/article/details/52744952 JDBC编程的六个步骤:    准备工作中导入ojdbc文件,然后右键选中添加路 ...

  9. Java 五子棋小游戏

    package Day8_06; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import ...

  10. PHP 循环删除无限分类子节点

    <?php private function _deleteSubNode($ids){ $subNodes = array(); $mod = D('Node'); foreach (expl ...