【问题标题】:request.on in http.createServer(function(request,response) {});http.createServer 中的 request.on(function(request,response) {});
【发布时间】:2016-05-07 21:00:12
【问题描述】:
var http = require('http');

var map = require('through2-map');

uc = map(function(ch) {    
  return ch.toString().toUpperCase();  
});

server = http.createServer(function(request, response) {
  request.on('data',function(chunk){
      if (request.method == 'POST') {
         //change the data from request to uppercase letters and 
         //pipe to response. 
      }
    });
});
server.listen(8000);

我对上面的代码有两个问题。首先,我阅读了request的文档,它说request是IncomingMessage的一个实例,它实现了Readable Stream。但是,我在 Stream 文档中找不到 .on 方法。所以我不知道 request.on 中的回调函数中的哪个块。其次,我想对请求中的数据进行一些操作,并将其传递给响应。我应该从块还是从请求中管道?感谢您的考虑!

【问题讨论】:

  • 关于However, I couldn't find .on method in the Stream documentation. 这是因为Stream实现了EventEmitter(文档说All streams are EventEmitters)。您必须在nodejs.org/api/events.html 上查看此特定方法。否则我没有清楚地理解你的问题。基本上,您应该将请求流通过管道传输到响应流中。流由从一端写入另一端的数据块组成。
  • 块是流吗?此外,每当有人向该服务器发送请求时,整个事情都会变成一个块吗?如果两个人发送两个请求,那会是两个块吗?

标签: node.js node.js-stream


【解决方案1】:

块是流吗?

不。流是整个数据块被发送的流。 一个简单的例子,如果你读取一个 1gb 的文件,一个流会按 10k 的块读取它,每个块都会以正确的顺序从头到尾通过你的流。 我以文件为例,但套接字、请求或任何流均基于该想法。

此外,每当有人向该服务器发送请求时,整个事情都会成为一个块吗?

在http请求的特殊情况下,只有请求体是一个流。它可以是发布的文件/数据。或响应的响应正文。在将主体写入套接字之前,标头被视为应用于请求的对象。

一个小例子,帮助你写一些具体的代码,

var through2 = require('through2');

var Readable = require('stream').Readable;

var s1 = through2(function transform(chunk, enc, cb){
  console.log("s1 chunk %s", chunk.toString())
  cb(err=null, chunk.toString()+chunk.toString() )
});

var s2 = through2(function transform(chunk, enc, cb){
  console.log("s2 chunk %s", chunk.toString())
  cb(err=null, chunk)
});

s2.on('data', function (data) {
  console.log("s2 data %s", data.toString())
})

s1.on('end', function (data) {
  console.log("s1 end")
})

s2.on('end', function (data) {
  console.log("s2 end")
})

var rs = new Readable;
rs.push('beep '); // this is a chunk
rs.push('boop'); // this is a chunk
rs.push(null); // this is a signal to end the stream

rs.on('end', function (data) {
  console.log("rs end")
})

console.log(
  ".pipe always return piped stream: %s", rs.pipe(s1)===s1
)

s1.pipe(s2)

我想建议您阅读更多内容:

【讨论】:

    【解决方案2】:

    所有 Streams 都是 EventEmitter (docs) 的实例,这就是 .on 方法的来源。

    关于第二个问题,您必须从 Stream 对象(在本例中为request)进行管道传输。 "data" 事件以BufferString(事件侦听器中的"chunk" 参数)而不是流的形式发出数据。

    通常通过实现Transform 流(docs)来操作流。尽管有许多 NPM 包可以使这个过程变得更简单(如 through2-map 等),但实际上它们会产生 Transform 流。

    考虑以下几点:

        var http = require('http');
    
        var map = require('through2-map');
    
        // Transform Stream to uppercase
        var uc = map(function(ch) {    
          return ch.toString().toUpperCase();  
        });
    
        var server = http.createServer(function(request, response) {
          // Pipe from the request to our transform stream
          request
            .pipe(uc)
            // pipe from transfrom stream to response
            .pipe(response);
        });
        server.listen(8000);
    

    你可以通过运行 curl 来测试:

    $ curl -X POST -d 'foo=bar' http://localhost:8000
    # logs FOO=BAR
    

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多