首页域名资讯 正文

如何编网站的HTTP 反向代理服务器

2024-10-07 5 0条评论

如何编网站的HTTP 反向代理服务器

  • 作者:新网
  • 来源:新网
  • 浏览:100
  • 2018-02-24 17:46:34

为了简化从 Readable Stream 监听 data 事件来获取数据并使用 Writable Stream 的 write() 方法来输出,可以使用 Readable Stream 的 pipe() 方法。那么如何编写 HTTP 反向代理服务器?

 为了简化从 Readable Stream 监听 data 事件来获取数据并使用 Writable Stream 的 write() 方法来输出,可以使用 Readable Stream 的 pipe() 方法。那么如何编写 HTTP 反向代理服务器?

简单版本   以下是实现一个简单 HTTP 反向 代理服务器的各个文件和代码(没有任何第三方库依赖), 为了使代码更简洁,使用了一些最新的 ES 语法特性,需要使用 Node v8.x 最新版本来运行 :   文件 proxy.js :   const http = require("http");   const assert = require("assert");   const log = require("./log");   /** 反向代理中间件 */   module.exports = function reverseProxy(options) {   assert(Array.isArray(options.servers), "options.servers 必须是数组");   assert(options.servers.length > 0, "options.servers 的长度必须大于 0");   // 解析 服务器地址,生成 hostname 和 port   const servers = options.servers.map(str => {   const s = str.split(":");   return { hostname: s[0], port: s[1] || "80" };   });   // 获取一个后端服务器,顺序循环   let ti = 0;   function getTarget() {   const t = servers[ti];   ti++;   if (ti >= servers.length) {   ti = 0;   }   return t;   }   // 生成监听 error 事件函数,出错时响应 500   function bindError(req, res, id) {   return function(err) {   const msg = String(err.stack || err);   log("[%s] 发生错误: %s", id, msg);   if (!res.headersSent) {   res.writeHead(500, { "content-type": "text/plain" });   }   res.end(msg);   };   }   return function proxy(req, res) {   // 生成代理请求信息   const target = getTarget();   const info = {   ...target,   method: req.method,   path: req.url,   headers: req.headers   };   const id = `${req.method} ${req.url} => ${target.hostname}:${target.port}`;   log("[%s] 代理请求", id);   // 发送代理请求   const req2 = http.request(info, res2 => {   res2.on("error", bindError(req, res, id));   log("[%s] 响应: %s", id, res2.statusCode);   res.writeHead(res2.statusCode, res2.headers);   res2.pipe(res);   });   req.pipe(req2);   req2.on("error", bindError(req, res, id));   };   };   文件 log.js :   const util = require("util");   /** 打印日志 */   module.exports = function log(...args) {   const time = new Date().toLocaleString();   console.log(time, util.format(...args));   };   说明:   log.js 文件实现了一个用于打印日志的函数 log() ,它可以支持 console.log() 一样的用法,并且自动在输出前面加上当前的日期和时间,方便我们浏览日志   reverseProxy() 函数入口使用 assert 模块来进行基本的参数检查,如果参数格式不符合要求即抛出异常,保证可以第一时间让开发者知道,而不是在运行期间发生各种不可预测的错误。   getTarget() 函数用于循环返回一个目标服务器地址   bindError() 函数用于监听 error 事件,避免整个程序因为没有捕捉网络异常而崩溃,同时可以统一返回出错信息给客户端。   以上就是小编对于编写 HTTP 反向代理服务器的建议。  

文章版权及转载声明

本文作者:亿网 网址:https://edns.com/ask/post/170739.html 发布于 2024-10-07
文章转载或复制请以超链接形式并注明出处。