Node.js - 创建代理,为什么需要request.pipe?

时间:2014-03-30 03:07:55

标签: node.js

有人可以解释这段代码来创建代理服务器。除了最后一块之外,一切都有意义。 request.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);

2 个答案:

答案 0 :(得分:4)

  

我在这里缺少什么? [...] http.request方法已经将请求包含在选项var。


http.request()实际上并未立即完整地发送请求:

  

[...] http.request()必须始终致电req.end()以表示您已完成请求 - 即使没有数据写入请求正文。

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

var req = http.request(options);

req.write(JSON.stringify({
    // ...
}));

req.end();
当你有一个可读的流时,

.pipe()只是一个选项,因为它.end() the client request by default


虽然,由于GET请求很少有需要管道或书写的正文,因此您通常可以使用http.get()代替.end()本身:

  

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

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

答案 1 :(得分:1)

简答:事件循环。我不想在我的屁股上说太多话,这就是node.js既美观又复杂的地方,但请求并不是在声明代理的行上严格制定的:它是's' s添加到事件循环中。因此,当您连接管道时,一切都按预期工作,来自传入请求的管道>代理>外向响应。这是异步代码的神奇/混乱!