GuillaumeC
GuillaumeC

Reputation: 555

Koa: Stream the HTML

With Koa, one of my route has a long process, and I would want to stream the body to start sending the css and the javascript so the browser can start processing it before it gets the data ( Google recommendation )

So this is how I'm trying to do it from a sandbox:


const app = new koa();

const readable = require("stream").Readable;
const s = new readable({ read(size) {} });

app.use(async (ctx, next) => {
  ctx.response.set("content-type", "txt/html");
  s.push("Hello, World!");
  ctx.body = s;
});

app.listen(8080);

When I access the site, instead of seeing the text Hello, World! my browser downloads a file, which contains Hello, World!.

I wonder if what I'm trying to achieve is possible with a stream ?

Upvotes: 1

Views: 1334

Answers (1)

Sebastian Hildebrandt
Sebastian Hildebrandt

Reputation: 2791

The trick is that ctx.type needs to be set:

'use strict';
const koa = require('koa');
const fs = require('fs');

const app = new koa();

// response
app.use(ctx => {
    if (ctx.request.url === '/stream') {
        const readable = require('stream').Readable
        const s = new readable({ read() { } });
        // stream data
        ctx.response.set("content-type", "txt/html");
        ctx.type = 'html';                  // <-- THIS is the important step!
        s.push('STREAM: Hello, World!');
        s.push(null); // indicates end of the stream
        ctx.body = s;
    } else if (ctx.request.url === '/file') {
        // stream file
        const src = fs.createReadStream('./big.file');
        ctx.response.set("content-type", "txt/html");
        ctx.body = src;
    } else {
        // normal KOA response
        ctx.body = 'BODY: Hello, World!';
    }
});

app.listen(8080);

This example shows

  • standard responses (localhost:8080/)
  • streams from file to file (localhost:8080/file)
  • streams from readable stream to html (localhost:8080/stream)

Upvotes: 1

Related Questions