搞点事情,使用node搭建反向代理

导语

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

一、实现反向代理

做为一个前端工程师,写代理脚本第一选择肯定是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。

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

时间: 2024-10-12 01:28:28

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

windows环境下安装apache及使用apache搭建反向代理

一.配置Apache平台软件 1.下载apache软件 http://httpd.apache.org/ 从Apache官网下载windows安装版的Apache服务器了,现在分享给大家. 2.方法/步骤如下: 2.1.进入apache服务器官网http://httpd.apache.org/,这里我们以下载稳定版的httpd 2.2.29为例,点击download. 2.2.download.cgi页面,往下翻找到2.2.29版本,其中有两个下载选项 Source: httpd-2.2.29.

Vue Nginx Node PM2 反向代理 项目部署

Vue Nginx Node PM2 项目部署 个人回忆使用,不是太详细,会的人应该能懂. 服务器 阿里云购买的 ECS 有个服务器,建议买个域名,但是没有域名需要备案,比较麻烦,我的还在备案中,所以就用ip来做测试 ECS => 实例 => 安全组配置 => 配置规则 => 快速配置 打开80端口 不会的百度,一大堆 解析域名什么的,添加到解析列表里面,就好了 Node 测试项目是一个教程,前后端分离,便于测试 client node-app 两个部分 node 项目里面没啥说的

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

参考博文: Nginx反向代理实现Tomcat分布式集群 1. jdk 安装 jdk 下载网址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 执行如下: # cd /usr # mkdir java # cp /xx/jdk-8u171-linux-x64.tar.gz /usr/java/ # cd /usr/java # tar -zxvf jdk-8u171-linu

nginx搭建反向代理配置

一.安装gcc yum install gcc-c++ -y 二.安装nginx所需要的依赖库 yum -y install zlib-devel openssl-devel pcre-devel 三.如有安装老版本,则卸载. 查看:find -name nginx 卸载:yum remove nginx 四.下载nginx源码并解压.(源码去官网下载, 以下是官方链接) wget -c http://nginx.org/download/nginx-1.6.2.tar.gz tar -zxvf

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

最近看了反向代理和正向代理的东西,想到自己的node.js服务器是运行在3333端口的,也没有为他设置反向代理,node.js项目的一些静态文件是完全可以部署在Nginx上,以减少对node.js的请求. 着手开始做: 1.Nginx依赖gcc,pcre,zlib,openssl之类的库,通过rpm -qa | grep gcc查询,没有的话都安装上. 2.Nginx安装 准备工作 a) 创建用户nginx使用的www用户.    # groupadd  www  #添加www组       

搭建nginx反向代理用做内网域名转发

基于域名的7层转发的实现(NAT+反向代理) 在实际办公网中,因为出口IP只有一个,要实现对外提供服务的话就必须得做端口映射,如果有多个服务要对外开放的话,这只能通过映射不同端口来区分,这在实际使用过程中非常的痛苦(记忆困难.一一对应关系也没有规律.访问的时候还得加端口),这个痛苦的问题用表格的形式来形象的描述如下: Public IP Public Port Number Internal IP Internal Port Number Note 1.1.1.1 80 192.168.1.10

在Linux系统下使用Docker以及Weave搭建Nginx反向代理

Hi, 今天我们将会学习如何使用 Weave 和 Docker 搭建 Nginx 的反向代理/负载均衡服务器.Weave 可以创建一个虚拟网络将 Docker 容器彼此连接在一起,支持跨主机部署及自动发现.它可以让我们更加专注于应用的开发,而不是基础架构.Weave 提供了一个如此棒的环境,仿佛它的所有容器都属于同个网络,不需要端口/映射/连接等的配置.容器中的应用提供的服务在 weave 网络中可以轻易地被外部世界访问,不论你的容器运行在哪里.在这个教程里我们将会使用 weave 快速并且简单

Nginx反向代理缓存服务器搭建

Nginx反向代理 代理服务可简单的分为正向代理和反向代理: 正向代理: 用于代理内部网络对Internet的连接请求(如VPN/NAT),客户端指定代理服务器,并将本来要直接发送给目标Web服务器的HTTP请求先发送到代理服务器上, 然后由代理服务器去访问Web服务器,并将Web服务器的Response回传给客户端: 反向代理: 与正向代理相反,如果局域网向Internet提供资源,并让Internet上的其他用户可以访问局域网内资源, 也可以设置一个代理服务器, 它提供的服务就是反向代理.

ubuntu 16.04利用docker搭建java+tomcat+nginx反向代理/动静分离

ubuntu 16.04利用docker搭建java+tomcat+nginx反向代理 新建两个docker容器 docker run -it --name Tomcat-mysql -v /mnt:/mnt -p 8866:80 -p 33006:3306 ubuntu /bin/bash docker run -itd --name webserver -p 8888:80 -v /mnt/:/mnt/ ubuntu /bin/bash [email protected]:~# docker