NodeJS实现代理转发

最近做项目的时候,有一个项目需求是,通过网关应用,请求到代理服务器,代理服务器自动转发请求到目标地址,请求链路:网关应用(内网服务器)->代理服务器->目标网站

网关应用是统一做请求外发的出口,所有接出到外部网络的请求都需要经过网关,但是由于密码套件版本差异,内网密码套件比较旧,导致请求握手失败。
握手失败
最后经过讨论,商量在服务器上起一个简单应用,专门实现做代理转发。在 Node.js 中使用 HTTPS 代理需要使用 axios-https-proxy-fix 模块来创建代理实例,该模块需要在 https 模块中使用。

在服务器上搭建nodejs服务的步骤:

1、服务器要支持nodeJS。下载安装请参考:NodeJS中文网

2、初始化一个Node项目。npm init

npm init配置说明

3、安装axios-https-proxy-fix依赖。npm install axios-https-proxy-fix

4、在npm init生成的项目下,新建一个.js文件(request.js),实现自己的业务逻辑。

以下是业务逻辑代码:

const http = require("http");
const axios = require('axios-https-proxy-fix'); // 使用 axios-https-proxy-fix 版本来代替 axios。
axios.defaults.timeout = 60 * 1000; //60秒过期

const targetHost = 'https://www.baidu'; //目标地址
const proxyHost = '101.101.101.101'; //代理地址
const token = 'Token abcd'; // 请求token,作为请求头传参

function onRequest(request, response) {
  console.log('onRequest')
  try {
    //target HOST IP + REQUEST URL 
    const url = targetHost + request.url;
    console.log("url", url);

    // 创建实例
    const instance = axios.create({
      baseUrl: targetHost,
      proxy: {
        protocol: 'http',
        host: proxyHost,
        port: 8080
      },
      headers: {
        'authorization': token,
        'Content-Type': 'application/json',
      },
    })
    if (request.method === 'POST') {
      //发送post请求
      postRequest(url, request, response, instance);
    } else {
      //发送get请求
      getRequest(url, request, response, instance);
    }
    // axios拦截器会将数据截取,此处需要将所有数据都返回
    instance.interceptors.response.use(resp => {
      console.log(resp.data);
      return resp;
    })

  } catch (error) {
    console.log('try catch err', error);
    response.writeHead(200, { "Content-Type": "application/json" });
    response.write(JSON.stringify({ returnMsg: new String(error) }));
    response.end();
  }
}

/**
 * 发送 post 请求
 * @param {String} url 完整请求地址 host+api
 * @param {*} request http createServer返回的 RequestListener  request对象中,可获取method\headers\url等信息
 * @param {*} response http createServer返回的 response
 * @param {*} instance axios 请求实例
 */
function postRequest(url, request, response, instance) {
  request.on('data', function (data) {
    instance.post(url, decodeURIComponent(data)).then((res) => {
      response.writeHead(200, { "Content-Type": "application/json" });
      response.write(JSON.stringify(res.data));
      response.end();
    })
      .catch((error) => {
        const data = error && error.response && error.response.data;
        const status = (error && error.response && error.response.status) || 200;
        response.writeHead(status, { "Content-Type": "application/json" });
        response.write(JSON.stringify({ returnMsg: data || '' }));
        response.end();
      })
  });
}

/**
 * 发送 get 请求
 * @param {String} url 完整请求地址 host+api
 * @param {*} request http createServer返回的 RequestListener  request对象中,可获取method\headers\url等信息
 * @param {*} response http createServer返回的 response
 * @param {*} instance axios 请求实例
 */
function getRequest(url, request, response, instance) {
  instance.get(url).then((res) => {
    response.writeHead(200, { "Content-Type": "application/json" });
    response.write(JSON.stringify(res.data));
    response.end();
  })
    .catch((error) => {
      const data = error && error.response && error.response.data;
      const status = (error && error.response && error.response.status) || 200;
      response.writeHead(status, { "Content-Type": "application/json" });
      response.write(JSON.stringify({ returnMsg: data || '' }));
      response.end();
    })
}

http.createServer(onRequest).listen(2444);
console.log('Server running in 127.0.0.1:2444')

5、运行项目。node request.js

一些自己的踩坑记录

1、JavaScript在运行之前不需要编译,因此也不会检查错误指导遇到这个错误为止,而Node服务有一个很难受的点就是,如果JS报错了,服务直接就停了,如果你需要一直让服务处于运行状态,那建议一定要在逻辑代码最外层增加try catch避免直接报错。
2、另外为了避免报错就停掉服务的情况,加了一个处理:联合使用nohup和&让进程后台运行,代替直接node+文件名启动服务的方式。

参考链接:
nodejs使用axios代理https失败的解决方案
Linux中nohup命令使用介绍

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值