将文本流从 NodeJS 传递到浏览器

2024-04-16

我正在尝试将 NodeJS 中处理的文本文件流式传输到浏览器。
以下是处理前的文本文件。
该文件名为 dbUsers.json。

{"userId":443,"email":"[email protected] /cdn-cgi/l/email-protection","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567439821109,"deleted":false}
{"userId":447,"email":"[email protected] /cdn-cgi/l/email-protection","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567439909013,"deleted":false}
{"userId":451,"email":"[email protected] /cdn-cgi/l/email-protection","hashedPassword":"36583a77a098c02ef111e2f2521d77b58e420f2bc7e9bf930ec24b21d42ea2e0","timeStamp":1567443638340,"deleted":false}
...

处理后,我可以使用以下命令将数据流式传输到 NodeJS 服务器上的新文件:

// Create a writable stream and specify the file which will receive the data from the readable stream.
let destinationStream = fs.createWriteStream(_data.baseDir + '/dbPermissions/dbUsers' + '/' + 'test' + '.txt', {flags : 'a'});


pipeline
(
  sourceStream,
  destinationStream,
  function(error){if(error){console.log('There was an error.');}}
);

新文件显示按预期处理的数据。
某些字段已被删除,并且标记为删除的记录已被删除。
这表明 sourceStream 在 NodeJS 中运行。
新文件中的数据现在如下:

{"userId":443,"email":"[email protected] /cdn-cgi/l/email-protection","timeStamp":1567439821109}
{"userId":447,"email":"[email protected] /cdn-cgi/l/email-protection","timeStamp":1567439909013}
{"userId":451,"email":"[email protected] /cdn-cgi/l/email-protection","timeStamp":1567443638340}
...

在将 sourceStream 流式传输到客户端浏览器之前将其记录到 NodeJS 控制台会产生以下输出。

Readable {
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: BufferList { head: [Object], tail: [Object], length: 45 },
     length: 3035,
     pipes:
      WriteStream {
        _writableState: [WritableState],
        writable: true,
        domain: null,
        _events: [Object],
        _eventsCount: 6,
        _maxListeners: undefined,
        path:
         'C:\\Users\\user\\Desktop\\Tutorials\\iotajs\\ias\\accounting\\/dbPermissions/dbUsers/test.txt',
        fd: null,
        flags: 'a',
        mode: 438,
        start: undefined,
        autoClose: true,
        pos: undefined,
        bytesWritten: 0,
        closed: false },
     pipesCount: 1,
     flowing: true,
     ended: true,
     endEmitted: false,
     reading: false,
     sync: true,
     needReadable: false,
     emittedReadable: true,
     readableListening: false,
     resumeScheduled: true,
     paused: false,
     emitClose: true,
     destroyed: false,
     defaultEncoding: 'utf8',
     awaitDrain: 0,
     readingMore: true,
     decoder: null,
     encoding: null },
  readable: true,
  domain: null,
  _events:
   [Object: null prototype] {
     close: [ [Function], [Function: onclose] ],
     end: [ [Function: onend], [Function] ],
     finish: [Function: onfinish],
     error: [Function: onerror],
     data: [Function: ondata] },
  _eventsCount: 5,
  _maxListeners: undefined }
Returning this response:  200
Returning this response:  200

当将 sourceStream 流式传输到浏览器然后注销到浏览器的控制台时,输出与上面相同。
所以我确信 sourceStream 会完好无损地到达客户端。

我需要处理的数据可能被锁定在许多 上面对象的 buffer 属性,现在称为responseTextStream 客户端浏览器。

我的问题是我不知道如何访问其中的信息 我也不知道如何将它们从数字转换回文本。

以下是我希望的客户端浏览器中的功能 使用缓冲区中的数据。这就是我需要帮助的地方 - 我不知道如何访问该流。谢谢,约翰

// Populate the dbUsersList webpage with user records.
app.loadUsersListPage = function()
{  
  // Ask the server for the JSON records found in the dbUsers file.
  // Then run the callback function defined here which inserts rows into the usersListTable on the webpage
  // and populates them with data from the file of JSON records returned.
  app.client.request(undefined,'api/aUsers','GET',QueryStringObject,undefined,function(statusCode,responseTextStream)
  {
    // if the call to handlers._users.get which is mapped to api/aUsers called back success.
    if(statusCode == 200) 
    {
      // The streamed data can be seen on the console as a buffer full of numbers
      console.log(responseTextStream._readableState.buffer.head.data.data);

      // Create a handle which can be used to manipulate the table on the webpage.
      var table = document.getElementById("usersListTable");


      // The pseudocode below does not work but is shows what I hope to accomplish. 
      // The line below does not help to access the stream. This is where I need help.
      // What line or lines of code would facilitate access to the stream and allow 
      // processing it as a string, character by character, as shown below.
      var Astr = responseTextStream;

      var line = "";

      for(var i=0; i<Astr.length; i++)
      {
        var chr = String.fromCharCode(Astr[i]);
        if(chr == "\n" || chr == "\r")
        {
          // Look at each line of json at the console as it is consumed.
          console.log("line: ",line);

          // Turn the line, which is a json string, back into a json object 
          var recordObject = JSON.parse(line);

          if(recordObject)
          {
            // Insert a new row in the table.
            var tr = table.insertRow(-1);
            // Make the new row a member of the class 'checkRow'
            tr.classList.add('checkRow');

            // Insert five new cells into the new row.
            var td0 = tr.insertCell(0);
            var td1 = tr.insertCell(1);
            var td2 = tr.insertCell(2);   
            var td3 = tr.insertCell(3);          

            // load the new cells with data from the recordObject.
            td0.innerHTML = recordObject.userId;      
            td1.innerHTML = recordObject.email;
            td2.innerHTML = recordObject.timeStamp;      
            td3.innerHTML = '<a href="/users/edit?email=' + recordObject.userId + '">View / Edit / Delete</a>';
          } // End of: if(recordObject)

          // clear the line buffer to start the next line.
          line = "";

        } // End of: if(chr == "\n" || chr == "\r"){do stuff}
        else 
        {
            line += chr;
        }           

      }; // End of: for(var i=0; i<Astr.length; i++){...}

    } // End of: if the call to handlers._users.get which is mapped to api/aUsers called back successfully.

  }); // End of: app.client.request(undefined,'api/checks','GET'...

} // End of: app.loadUsersListPage = function(){...}
// End of: Populate the dbUsersList webpage with user records.

根据 @Brad 的回答,我使用了他的代码 结果不令人满意。下面是布拉德的代码,下面是 他的代码在该点返回的对象value是 记录到控制台。它与之前的缓冲区是同一个对象 扩大检查。我的问题仍然是返回的对象 只是一堆包含一堆数字的缓冲区,而不是 我可以用它做一些事情的字符串。记录时value到 控制台我希望在人类中看到修改后的数据的每一行 可读格式。我什么没做,或者我做错了什么? 谢谢,约翰

// Populate the dbUsersList webpage with user records.
app.loadUsersListPage = async function()
{  
  // Define which users will be retrieved from dbUsers.json
  // This is not being used for now so all records will be retrived.
  var QueryStringObject = {};

  // Define a client function that calls for data from the server.
  const fetchPromise = fetch('api/aUsers')
  .then
  (
    (res) => 
    {
      // Verify that we have some sort of 2xx response that we can use
      if (!res.ok) 
      {
        throw res;
      }

      // If no content, immediately resolve, don't try to parse JSON
      if (res.status === 204) 
      {
        return;
      }

      // Initialize variable to hold chunks of data as they come across.
      let textBuffer = '';

      // This does not seem to be used. Delete this after everything else is working.
      const self = this;

      // Process the stream.
      return res.body

      // Decode as UTF-8 Text
      .pipeThrough
      (
        new TextDecoderStream()
      )

      // Split on lines
      .pipeThrough
      (
        new TransformStream
        (
          {
            transform(chunk, controller) 
            {
              textBuffer += chunk;

              const lines = textBuffer.split('\n');

              for (const line of lines.slice(0, -1)) 
              {
                controller.enqueue(line);
              } // End of: for (const line ...)

              textBuffer = lines.slice(-1)[0];
            }, // End of: Transform(chunk, controller){do stuff}

            flush(controller) 
            {
              if (textBuffer) 
              {
                controller.enqueue(textBuffer);
              } // End of: if (textBuffer)
            } // End of: flush(controller){do stuff}
          } // End of: parameters for new TransformStream
        ) // End of: call to constructor new TransformStream
      ) // End of: parameters for pipeThrough - Split on lines

      // Parse JSON objects
      .pipeThrough
      (
        new TransformStream
        (
          {
            transform(line, controller) 
            {
              if (line) 
              {
                controller.enqueue
                (
                  JSON.parse(line)
                ); //End of: call to controller.enqueue function
              } // End of: if (line)
            } // End of: transform function
          } // End of: parameter object for new TransformStream
        ) // End of: new TransformStream parameters
      ); // End of: parameters for .pipeThrough - Parse JSON objects
    } // End of: .then callback function instruction for fetch
  ); // End of: .then callback parameters for fetch


  // Call to function which asks server for data.
  const res = await fetchPromise;

  const reader = res.getReader();

  function read() 
  {
    reader.read()
    .then
    (
      ({value, done}) => 
      {
        if (value) {
          // Your object will be here
          console.log('I got to this point');
          console.log(value);
        }
        if (done) {
          return;
        }
        read();
      }
    );
  }

  read();

} // End of: app.loadUsersListPage = function(){...}
// End of: Populate the dbUsersList webpage with user records.

这是 Brad 的代码记录时我得到的结果value到控制台。这是 和我之前得到的一样。我希望看到一行行文字。什么 是我没做,还是我做错了什么?谢谢,约翰

{_readableState: {…}, readable: true, domain: null, _events: {…}, _eventsCount: 0}
domain: null
readable: true
_events: {}
_eventsCount: 0
_readableState:
awaitDrain: 0
buffer:
head:
data:
data: (65) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 52, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 98, 111, 98, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 51, 57, 56, 50, 49, 49, 48, 57, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 52, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 97, 108, 105, 99, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 51, 57, 57, 48, 57, 48, 49, 51, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 53, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 99, 108, 105, 102, 102, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 52, 51, 54, 51, 56, 51, 52, 48, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 53, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 97, 114, 103, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 52, 51, 55, 54, 53, 54, 48, 57, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 53, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 99, 108, 105, 110, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 52, 51, 56, 49, 51, 49, 54, 55, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 54, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 98, 121, 114, 111, 110, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 52, 51, 57, 52, 50, 48, 57, 54, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 54, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 105, 108, 116, 111, 110, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 52, 52, 50, 48, 55, 53, 52, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 55, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 97, 114, 110, 111, 108, 100, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 52, 52, 52, 50, 51, 57, 55, 53, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 55, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 115, 97, 108, 108, 121, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 52, 56, 57, 56, 57, 52, 54, 57, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 57, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 97, 114, 118, 105, 110, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 53, 48, 51, 56, 50, 52, 54, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 57, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 110, 97, 110, 99, 121, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 53, 48, 52, 49, 55, 52, 52, 57, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 52, 57, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 102, 114, 101, 100, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 53, 48, 52, 51, 48, 55, 52, 50, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 48, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 97, 108, 101, 120, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 52, 53, 52, 56, 55, 57, 55, 53, 51, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 48, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 104, 101, 114, 109, 97, 110, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 53, 48, 54, 48, 50, 55, 50, 49, 55, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (69) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 49, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 97, 114, 103, 114, 101, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 53, 53, 55, 53, 50, 49, 51, 55, 51, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (69) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 49, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 115, 121, 110, 116, 104, 105, 97, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 53, 53, 55, 53, 55, 51, 56, 52, 48, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 49, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 99, 111, 110, 110, 101, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 53, 53, 55, 54, 48, 55, 51, 56, 55, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 50, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 97, 114, 103, 111, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 55, 53, 53, 56, 53, 57, 57, 50, 48, 48, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 50, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 100, 101, 110, 105, 115, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 48, 54, 54, 50, 56, 55, 53, 54, 48, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 51, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 112, 104, 105, 108, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 48, 54, 54, 56, 49, 50, 48, 55, 48, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 51, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 111, 114, 103, 97, 110, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 48, 55, 55, 53, 55, 55, 56, 53, 56, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 51, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 108, 117, 107, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 48, 55, 50, 53, 48, 49, 51, 55, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 52, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 119, 97, 114, 114, 101, 110, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 48, 56, 52, 55, 50, 54, 56, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 53, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 119, 105, 108, 98, 117, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 49, 49, 49, 56, 54, 51, 55, 54, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 53, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 112, 97, 117, 108, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 49, 49, 50, 50, 52, 55, 57, 49, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (70) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 53, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 102, 108, 111, 114, 97, 110, 99, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 53, 50, 50, 48, 48, 51, 50, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (69) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 54, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 117, 109, 102, 111, 114, 100, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 53, 50, 51, 55, 53, 57, 56, 50, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 54, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 98, 97, 114, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 53, 55, 55, 48, 49, 57, 55, 49, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 55, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 104, 111, 109, 101, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 53, 55, 55, 57, 48, 53, 49, 53, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (69) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 55, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 102, 97, 108, 107, 110, 101, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 54, 51, 48, 52, 55, 52, 53, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (70) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 55, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 97, 110, 100, 101, 114, 115, 111, 110, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 57, 54, 51, 56, 53, 50, 53, 51, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 56, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 98, 97, 114, 114, 121, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 49, 57, 55, 55, 52, 54, 48, 55, 51, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 56, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 98, 97, 114, 110, 101, 121, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 50, 51, 54, 54, 52, 54, 54, 54, 50, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 57, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 98, 101, 116, 116, 121, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 50, 51, 54, 55, 52, 57, 54, 51, 54, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 57, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 115, 116, 101, 118, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 50, 52, 52, 56, 49, 56, 48, 50, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 53, 57, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 115, 104, 105, 114, 108, 121, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 50, 56, 49, 54, 49, 54, 50, 53, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 48, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 97, 103, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 50, 56, 49, 56, 57, 54, 52, 50, 55, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (71) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 48, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 99, 111, 110, 115, 116, 97, 110, 99, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 50, 48, 54, 56, 49, 53, 54, 54, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (68) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 49, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 109, 97, 114, 115, 104, 97, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 50, 48, 56, 55, 55, 57, 56, 54, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 49, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 103, 114, 101, 103, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 50, 49, 49, 53, 55, 49, 56, 53, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 50, 51, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 112, 101, 116, 101, 114, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 50, 49, 50, 48, 55, 55, 51, 55, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (67) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 50, 55, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 99, 105, 110, 100, 121, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 56, 52, 52, 52, 49, 52, 54, 49, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 51, 49, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 114, 111, 115, 101, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 56, 52, 52, 55, 50, 49, 48, 57, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (66) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 51, 53, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 98, 97, 114, 98, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 56, 52, 53, 51, 57, 52, 50, 52, 125, 10]
type: "Buffer"
__proto__: Object
next:
data:
data: (69) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 51, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 103, 105, 108, 98, 101, 114, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 56, 52, 53, 57, 56, 56, 54, 55, 125, 10]
type: "Buffer"
__proto__: Object
next: null

length: 45
tail:
data:
data: (69) [123, 34, 117, 115, 101, 114, 73, 100, 34, 58, 54, 51, 57, 44, 34, 101, 109, 97, 105, 108, 34, 58, 34, 103, 105, 108, 98, 101, 114, 116, 64, 103, 109, 97, 105, 108, 46, 99, 111, 109, 34, 44, 34, 116, 105, 109, 101, 83, 116, 97, 109, 112, 34, 58, 49, 53, 54, 56, 52, 56, 52, 53, 57, 56, 56, 54, 55, 125, 10]
type: "Buffer"
__proto__: Object
next: null

I did not include the entire object.

如上所示,返回的对象中包含许多缓冲区。我 认为每个缓冲区包含来自原始 dbUsers 的行/记录 文件删除了一些字段并删除了重复记录。我会 喜欢将这些缓冲区视为人类可读的文本。因为很多 缓冲区正在返回,最终我需要学习如何 遍历缓冲区,但现在我只是尝试转动 首先缓冲到文本中。布拉德此时处于劣势 因为他不在电脑旁边。所以他看不到我的代码 使用。无论如何,他好心地建议我尝试 toString() 功能。所以我在第一个缓冲区上尝试了以下代码行。console.log(value._readableState.buffer.head.data.data.toString());以下数字是结果。我希望有一串 文本。谁能看到我没有做什么?谢谢,约翰

123,34,117,115,101,114,73,100,34,58,52,52,51,44,34,101,109,97,105,108,34,58,34,98,111,98,64,103,109,97,105,108,46,99,111,109,34,44,34,116,105,109,101,83,116,97,109,112,34,58,49,53,54,55,52,51,57,56,50,49,49,48,57,125,10

尝试以下代码行后,我仍然得到数字不 控制台上的字母。console.log(value._readableState.buffer.head.data.data.toString('utf8'));谢谢,约翰


由于您使用的是 Chrome,因此您可以在一个漂亮的管道中使用 TextDecoderStream 和 TransformStream 等所有新功能,该管道流式传输来自 HTTP 响应的数据并解码行分隔的 JSON。看一下这个:

const fetchPromise = fetch(url, params).then((res) => {
  // Verify that we have some sort of 2xx response that we can use
  if (!res.ok) {
    throw res;
  }

  // If no content, immediately resolve, don't try to parse JSON
  if (res.status === 204) {
    return;
  }

  let textBuffer = '';

  const self = this;

  return res.body
    // Decode as UTF-8 Text
    .pipeThrough(new TextDecoderStream())

    // Split on lines
    .pipeThrough(new TransformStream({
      transform(chunk, controller) {
        textBuffer += chunk;
        const lines = textBuffer.split('\n');
        for (const line of lines.slice(0, -1)) {
          controller.enqueue(line);
        }
        textBuffer = lines.slice(-1)[0];
      },
      flush(controller) {
        if (textBuffer) {
          controller.enqueue(textBuffer);
        }
      }
    }))

    // Parse JSON objects
    .pipeThrough(new TransformStream({
      transform(line, controller) {
        if (line) {
          controller.enqueue(
            JSON.parse(line)
          );
        }
      }
    }));
});

现在,您可以像使用其他对象流一样使用这个新对象流:

  const res = await fetchPromise;
  const reader = res.getReader();
  function read() {
    reader.read().then(({value, done}) => {
      if (value) {
        // Your object will be here
      }
      if (done) {
        return;
      }
      read();
    });
  }
  read();

(注意:我尚未在此示例上下文中测试此代码...我从我的一个项目中修改了此代码,因此请仔细检查并根据您的特定目的进行调整。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将文本流从 NodeJS 传递到浏览器 的相关文章

随机推荐

  • 违反 - 未找到父键错误

    我出现以下错误 INSERT INTO GroupMembers VALUES Goldfrat Simon Palm ERROR at line 1 ORA 02291 integrity constraint SHAHA1 IAM IS
  • VS2010/C#4 的 C# 编译器错误 CS1628

    此编译器错误列在 C 编译器错误中MSDN http msdn microsoft com en us library we3011f5 28v vs 90 29 aspx适用于 VS2005 和 VS2008 但不适用于较新的版本 这会让
  • iOS VoiceOver“找不到标题”

    我有一个 UITableView 其中每个 UITableViewCell 有 2 个 UILabels 1 个标题和 1 个内容 标头的 AccessibilityTrait 设置为 header 使用辅助功能检查器检查模拟器屏幕时 我能
  • 如何在React功能组件中添加事件

    我有一个关于 React 函数式组件的问题 特别是关于函数式组件中的函数的问题 例如 import React useEffect from react const Component props gt useEffect gt windo
  • 扫描新指纹时如何触发KeyPermanentlyInvalidatedException

    如上所述here https stackoverflow com a 44926774 3142611 我正在尝试触发KeyPermanentlyInvalidatedException当新的指纹添加到设备但未触发此异常时 MyCode F
  • Python 中可用和已使用的系统内存? [复制]

    这个问题在这里已经有答案了 如何从 Python 获取可用和当前使用的内存 它需要是跨平台的 并且至少可以在 Windows Mac OS X 和 Linux 上运行 我想向我的应用程序中的用户报告没有足够的可用内存来继续 你应该看看psu
  • 使用 XSLT 转换 XML 时保留实体引用?

    使用 XSLT 2 0 转换 XML 时如何保留实体引用 对于我尝试过的所有处理器 默认情况下都会解析实体 我可以用xsl character map处理字符实体 但是文本实体呢 例如 这个 XML gt
  • C# Datagridview 不对 Checkbox 列进行排序

    当我将 Linq to sql 查询绑定到 datagridview 在其间使用 BindingSource 时 默认情况下这些列是可排序的 然而 布尔类型似乎并非如此 对于这些 datagridview 使用复选框列 但是当我单击标题时没
  • .NET 多线程变量访问

    我有一个有 4 个线程的应用程序 GUI 控制器 生产者 消费者 GUI 是不言自明的 控制器在进行一些初始设置后启动生产者和消费者线程 生产者创建项目并将它们放置在 环形缓冲区 的空闲槽中 消费者从 环形缓冲区 中取出项目并将其写入磁盘
  • 当 Git 或 TortoiseGit 出现冲突时,正确的提交/推送方式是什么?

    我们正在使用 git 和合并工作流程 我们有很多 git 新手 包括 我 要么有 SVN 或 CVS 背景 要么没有版本控制背景 根本不 这是我们经常遇到的问题 许多团队成员都是 使用 TortoiseGit 由于并发 合并冲突经常发生 改
  • 什么是准备好的陈述?它们与动态sql有何不同?

    我没有看到任何重复的问题 但想知道是否有人可以提供一些很好的例子 特别是围绕这些问题的最佳实践 准备好的语句是预编译的您可以在数据库上多次运行的语句 并且 SQLServer 不会在您每次运行它时解析或生成不同的执行计划 通常 您在客户端上
  • Python - 将枚举转换为 Django models.CharField 选择元组 [重复]

    这个问题在这里已经有答案了 我有这个枚举 class Animal Enum DOG dog CAT cat 在 Django 模型中我有这个 possible animals DOG dog cat cat animal models C
  • Android menuitem onclick处理程序的返回值

    在 android 中 当我在 xml 中定义 menuitem 的 onclick 处理程序时
  • Notepad++ 将鼠标悬停在链接或颜色上进行预览?

    我想知道是否有一个选择或plugin 这使我们能够悬停预览要么是CSS颜色 or image 像这样 而且如果你将鼠标悬停在 img src 上 预览图片 尝试 Notepad 快速颜色选择器 双击十六进制颜色 会弹出一个颜色选择器以及预览
  • 如何使我的布局能够向下滚动?

    我无法向下滚动屏幕查看 回复者 部分中的数据 如何使我的布局可滚动 只需将所有内容包裹在一个ScrollView
  • 从具有重复值的 MySQL 结果创建多维嵌套数组 (PHP)

    我目前正在使用 PDO fetchAll 函数从数据库中提取菜单数据 这样做会将查询结果的每一行放入以下结构的数组中 Array 0 gt Array MenuId gt mmnlinlm08l6r7e8ju53n1f58 MenuName
  • 如何使用python比较两个html文件

    我想使用 python 来比较两个 html 文件 例子 html 1 p i love it p html 2 h2 i love it diff 文件将如下所示 diff html h2
  • 从 Hashicorp 金库存储和检索文件

    我不知道如何在 hashcorpVault 中存储文件 我们的 PoC 用例是将 SSL 证书存储在特定路径 然后通过 HTTP API 下载它 我尝试使用 kv 秘密引擎 这似乎是最合适的 似乎您可以指定一个包含数据的文件来存储为 Has
  • 如何使用 OAUTH2 从 Java 访问 Outlook.office365.com IMAP?

    由于 Microsoft 宣布很快将无法再通过基本身份验证访问 Outlook IMAP 邮箱 因此我正在尝试弄清楚如何在 Java 中使用 OAUTH2 正确打开 IMAP 邮箱 但我总是收到错误代码 A1 NO AUTHENTICATE
  • 将文本流从 NodeJS 传递到浏览器

    我正在尝试将 NodeJS 中处理的文本文件流式传输到浏览器 以下是处理前的文本文件 该文件名为 dbUsers json userId 443 email email protected cdn cgi l email protectio