2012-04-19 64 views
2

我试图创建实验目的简单的node.js代理服务器,我想出了这个简单的脚本一个简单的代理服务器:实现如何使用Node.js

var url = require("url"); 
var http = require("http"); 
var https = require("https"); 

http.createServer(function (request, response) { 
    var path = url.parse(request.url).path; 

    if (!path.indexOf("/resource/")) { 
     var protocol; 
     path = path.slice(10); 
     var location = url.parse(path); 

     switch (location.protocol) { 
     case "http:": 
      protocol = http; 
      break; 
     case "https:": 
      protocol = https; 
      break; 
     default: 
      response.writeHead(400); 
      response.end(); 
      return; 
     } 

     var options = { 
      host: location.host, 
      hostname: location.hostname, 
      port: +location.port, 
      method: request.method, 
      path: location.path, 
      headers: request.headers, 
      auth: location.auth 
     }; 

     var clientRequest = protocol.request(options, function (clientResponse) { 
      response.writeHead(clientResponse.statusCode, clientResponse.headers); 
      clientResponse.on("data", response.write); 
      clientResponse.on("end", function() { 
       response.addTrailers(clientResponse.trailers); 
       response.end(); 
      }); 
     }); 

     request.on("data", clientRequest.write); 
     request.on("end", clientRequest.end); 
    } else { 
     response.writeHead(404); 
     response.end(); 
    } 
}).listen(8484); 

我不知道在哪里我错了,但当我尝试加载任何页面时,它给了我以下错误:

http.js:645 
    this._implicitHeader(); 
     ^
TypeError: Object #<IncomingMessage> has no method '_implicitHeader' 
    at IncomingMessage.<anonymous> (http.js:645:10) 
    at IncomingMessage.emit (events.js:64:17) 
    at HTTPParser.onMessageComplete (http.js:137:23) 
    at Socket.ondata (http.js:1410:22) 
    at TCP.onread (net.js:374:27) 

我想知道问题是什么。在node.js中进行调试比在Rhino中要困难得多。任何帮助将不胜感激。

+0

我在自己的电脑上运行了代码。因此,我通过转到“http:// localhost:8484/resource/http:// code.jquery.com/jquery.js”在我的Web浏览器中打开它。它应该已经提取了'jquery.js'文件并将其转发,但是它给了我上述错误。 – 2012-04-19 06:15:23

+0

我最初的猜测是因为你将函数传递给'data'和'end'。你可以尝试传递调用'clientRequest.write()'和'clientRequest.end()'的匿名函数吗?你现在拥有它的方式是传递函数,但是当它被调用时,它将没有适当的上下文('this')。 – loganfsmyth 2012-04-19 06:23:25

+0

你想获取URL内容吗? 'resource'后的URL – 2012-04-19 06:40:00

回答

3

正如我在评论中提到的那样,您的主要问题是您的.write.end调用没有被正确绑定到上下文,所以他们只会翻转并抛出错误。

由于固定,请求给出404,因为headers属性将拉动原始请求的host标头,localhost:8484。按照你的例子,这将发送到jquery.com的服务器,它将会404。你需要在代理之前删除host头。

在致电protocol.request之前添加此项。

delete options.headers.host; 
+0

谢谢你的帮助。它像一个魅力。我认为将'options.headers.host'设置为'location.host'而不是删除它是个好主意。 =) – 2012-04-19 07:23:16