8 行 Node.js 代码实现代理服务器
发布于 8 年前 作者 kaysonli 20166 次浏览 来自 分享

接触 Node.js 已有多年,一直喜欢它的单线程模型和异步IO特性,以及 JavaScript 语言本身的灵活性。同时,JavaScript 前后端通吃,在全栈开发领域具有独特的优势。今天就来看看作为服务端语言的 JavaScript,完成一个简单的代理服务器功能是多么容易。

简单地说,代理服务器就是代理用户访问目标站点的中介服务器。作为前端开发人员,代理的常见用途是跨域访问后台 API。当然,还可以用来科学上网。今天要分享的代码,就是跟科学上网有关。

话不多说,先上 code:

var express = require(‘express’); var request = require(‘request’); var app = express(); app.use(’/’, function(req, res) { var url = ‘https://www.baidu.com/’ + req.url; req.pipe(request(url)).pipe(res); }); app.listen(process.env.PORT || 3000); 不到 10 行的代码,就实现了简单的代理服务器功能。是不是很神奇? 熟悉 Node.js 的话应该很容易看明白这几行代码。首先加载 express 模块,这个是创建 HTTP 服务器的一个流行框架。然后是 request,它封装了 HTTP 请求的各种方法,让发起请求变得非常容易。接下来实例化一个 express 对象,设置访问路由。最后监听 3000 端口。 先看效果。保存上述代码到文件 proxy.js,在文件所在路径执行:

node proxy.js 用浏览器打开http://localhost:3000/

HTTP 代理 关键代码在路由处理方法内。

req.pipe(request(url)).pipe(res); 这个 pipe 方法很神奇,正如它的名字(管道)一样,它把浏览器的请求数据传给 request 客户端,然后将目标服务器的响应数据传回浏览器。这代码太TM简洁了! 那么,怎么实现科学上网呢?对,把代码放到没有网络封锁的服务器上运行,就OK了。比如,这个 任度搜 http://www.rendoso.com 背后就是 Google 代理。

21 回复

mark,感谢分享

先mark

来自酷炫的 CNodeMD

这个pipe 能实现将a 进程的socket 转发到b进程吗?

这段代码不是万能的。如果后端服务需要check host 头就有问题。。。

var http = require("http");
var server = http.createServer(function(req, res) {
  var opts = {
    host: "xxxxx",
    port: xxx,
    path: req.url,
    method: req.method,
    headers: req.headers
  };
  // 如果后端服务需要check host头的话,代理请求头就不能直接透明代理了
  // req.headers["host"] = opts.port ? (opts.host+":"+opts.port) : (opts.host)
  var proxy = http.request(opts, function(resProxy) {
    res.writeHead(resProxy.statusCode, resProxy.headers);
    resProxy.pipe(res);
  });
  req.pipe(proxy); 
});
server.listen(8080);

这个太简单了,静态资源怎么办,ajax怎么办。。

@zaaack 都处理了啊,只要是站内的相对路径

可以用restify 自豪地采用 CNodeJS ionic

这里面express可以用原生取代吧

框架都提供了对应的proxy包,比如koa-proxy

精间成两行

var http=require('http')
  ,request = require('request')
  ,proxyhandle=function(req, res) { req.pipe(request( 'http://www.google.com/search?q='+ req.url.split('=')[1])).pipe(res); };
http.createServer(proxyhandle).listen(process.env.PORT || 3000);
    

没啥这么热衷用node实现代理。nginx的代理还不够用?简单高效稳定。

@kaysonli 大部分静态资源都会有cdn,还有 ajax 的数据也可能有不同地址,因此一般的代理服务还需要客户端进行设置,比如 anyproxy

象 http/net 这些 模块的源码在哪里能看到 ?
https://github.com/sleeplessinc/net 这里面是空的

@yakczh 这些是node自带的模块,你可以去node在GitHub上的仓库去看https://github.com/nodejs/node/tree/master/lib

@kaysonli 象http这种应该跟平台无关,为什么没有用 c++ 写?

@yakczh 只是想尝试下Node.js,不觉得 JavaScript 更简单灵活吗?

回到顶部