Node.js – 创build一个代理,为什么request.pipe需要?

有人可以解释这个代码来创build一个代理服务器。 除了最后一块以外,一切都有意义。 request.pipe(代理 – 我不明白这是因为当代理被声明时,它会发出请求,并pipe理其对客户端响应的响应。我在这里丢失了什么?为什么我们需要pipe道原始请求到代理,因为http.request方法已经使请求包含在选项var中。

var http = require('http'); function onRequest(request, response) { console.log('serve: ' + request.url); var options = { hostname: 'www.google.com', port: 80, path: request.url, method: 'GET' }; var proxy = http.request(options, function (res) { res.pipe(response, { end: true }); }); request.pipe(proxy, { end: true }); } http.createServer(onRequest).listen(8888); 

我在这里错过了什么? http.request方法已经使请求包含在选项var中。


http.request()实际上并不实际发送完整的请求:

[…]使用http.request()必须始终调用req.end()来表示已完成请求 – 即使没有数据写入请求主体。

它创build的http.ClientRequest保持打开状态,以便可以将正文内容(如JSON数据)写入并发送到响应服务器:

 var req = http.request(options); req.write(JSON.stringify({ // ... })); req.end(); 

当你有一个可读的stream时, .pipe()只是一个选项,因为默认情况下它将会.end()客户端请求 。


虽然,由于GET请求很less有一个需要pipe道或写入的主体,所以通常可以使用http.get()来调用.end()本身:

由于大多数请求是没有实体的GET请求,Node提供了这种方便的方法。 这个方法和http.request()之间的唯一区别是它将方法设置为GET并自动调用req.end()

 http.get(options, function (res) { res.pipe(response, { end: true }); }); 

简短的回答:事件循环。 我不想说我的屁股太遥远了,这是node.js得到美丽和复杂的地方,但请求是不严格MADE在声明代理线:它被添加到事件循环。 所以,当你连接pipe道,一切正常,从传入的请求pipe道>代理>传出响应。 这是asynchronous代码的魔力/混乱!