添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've been trying to get a express app to send the response as stream.

var Readable = require('stream').Readable;
var rs = Readable();
app.get('/report', function(req,res) {
    res.statusCode = 200;
    res.setHeader('Content-type', 'application/csv');
    res.setHeader('Access-Control-Allow-Origin', '*');
    // Header to force download
    res.setHeader('Content-disposition', 'attachment; filename=Report.csv');
    rs.pipe(res);
    rs.push("USERID,NAME,FBID,ACCOUNT,SUBSCRIPTION,PRICE,STATE,TIMEPERIOD\n");
    for (var i = 0; i < 10; i++) {
        rs.push("23,John Doe,1234,500,SUBSCRIPITON,100,ACTIVE,30\n");
    rs.push(null);

It does print in the console when I replace "rs.pipe(res)" by "rs.pipe(process.stdout)". But how to make it work in an express app?

Error: not implemented
    at Readable._read (_stream_readable.js:465:22)
    at Readable.read (_stream_readable.js:341:10)
    at Readable.on (_stream_readable.js:720:14)
    at Readable.pipe (_stream_readable.js:575:10)
    at line "rs.pipe(res);"
                You need to subclass Readable, which needs to have a _read method. But why not just use res.write(...)?
– robertklep
                Aug 5, 2016 at 12:29

You don't need a readable stream instance, just use res.write():

res.write("USERID,NAME,FBID,ACCOUNT,SUBSCRIPTION,PRICE,STATE,TIMEPERIOD\n");
for (var i = 0; i < 10; i++) {
    res.write("23,John Doe,1234,500,SUBSCRIPITON,100,ACTIVE,30\n");
res.end();

This works because in Express, res is based on Node's own http.serverResponse, so it inherits all its methods (like write).

@chetandev your browser/client might buffer it, but Express or http doesn't. You can test this using a non-buffering TCP-client like nc/netcat. See this gist. – robertklep Jul 22, 2019 at 18:30
  • Put this code in your Express router.
  • Open a web browser
  • Go to http://yourdomain/yourrouterpath/stream
  • router.get('/stream', function (req, res, next) {
      //when using text/plain it did not stream
      //without charset=utf-8, it only worked in Chrome, not Firefox
      res.setHeader('Content-Type', 'text/html; charset=utf-8');
      res.setHeader('Transfer-Encoding', 'chunked');
      res.write("Thinking...");
      sendAndSleep(res, 1);
    var sendAndSleep = function (response, counter) {
      if (counter > 10) {
        response.end();
      } else {
        response.write(" ;i=" + counter);
        counter++;
        setTimeout(function () {
          sendAndSleep(response, counter);
        }, 1000)
                    Wow thank you so much for this answer. I was setting the content type to text/plain and couldn't figure out for the life of me why it wasn't streaming. You can also just not set the header, start writing, & it will work.
    – thefinnomenon
                    Mar 24 at 15:44
    

    I needed to stream a response in express in order to work with tar-stream. Here is how I did it in case it helps anyone.

    The requests are for a single file from a tar file stored on the server.

    const fs = require("fs"),
       tar = require("tar-stream");
    app.get("/fileFromTar/*", (req, res) => {
       const fileWanted = req.params[0],
          readStream = fs.createReadStream('myTarFile.tar'),
          extractor = tar.extract();
       extractor.on('entry', (header, stream, next) => {
          stream.on('end', next);
          if (header.name === fileWanted) {
             const { size } = header;
             res.set({
               "Content-Type": 'audio/flac', // or whichever one applies
               "Content-Length": size,
               "Content-Range": `bytes 0-${size}/${size}`
             stream.pipe(res);
          else stream.resume();
       readStream.pipe(extractor);
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.