Koa:流式传输 HTML

问题描述

使用 Koa,我的其中一条路线有一个很长的过程,我想流式传输正文以开始发送 css 和 javascript,以便浏览器可以在获取数据之前开始处理它(Google 推荐)

所以这就是我试图从沙箱中做到这一点的方式:


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);

当我访问该网站时,我的浏览器没有看到文本 Hello,World!,而是下载了一个包含 Hello,World!文件

我想知道我想要实现的目标是否可以通过流实现?

解决方法

诀窍是需要设置 ctx.type

'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);

这个例子展示了

  • 标准回复 (localhost:8080/)
  • 从文件到文件的流 (localhost:8080/file)
  • 从可读流到 html (localhost:8080/stream) 的流