代码之家  ›  专栏  ›  技术社区  ›  ar099968

Express.js:在chunk中发送响应

  •  1
  • ar099968  · 技术社区  · 3 周前

    在上是可能的 Express.js 以数据块形式发送响应?我试过了( online demo ):

    const express = require('express');
    const app = express();
    const port = 3111;
    
    const sleep = (ms) => {
      return new Promise((resolve) => setTimeout(resolve, ms));
    };
    
    app.get('/', async (req, res) => {
      res.setHeader('Content-Type', 'application/json');
      // flush to enable stream
      res.flushHeaders();
      res.write('[');
      for (let i = 1; i <= 1000; i++) {
        res.write(JSON.stringify(`data ${i}`));
        if (i + 1 <= 1000) {
          res.write(',');
        }
        await sleep(1);
      }
      res.write(']');
      res.end();
    });
    
    app.listen(port, () => {
      console.log(`App is live at http://localhost:${port}`);
    });
    

    但在谷歌Chrome和Postman上,只有当 res.end() 被调用

    1 回复  |  直到 3 周前
        1
  •  2
  •   Mina    3 周前

    有一些考虑因素

    1. 您应该添加一个正确的 Content-Type 对于流,例如 application/stream+json
    2. 请记住,浏览器和一些HTTP客户端可能会缓冲响应(它们不会在块到达时显示块,而是等到收到整个响应为止),因此您可能需要考虑使用javascript来处理响应。
    3. 你不需要 res.flushHeaders() Express 当您开始编写响应正文时自动处理它
    import express from "express";
    const app = express();
    
    const sleep = (ms) => {
        return new Promise((resolve) => setTimeout(resolve, ms));
    };
    
    app.get('/stream', async (_req, res) => {
        res.setHeader('Content-Type', 'application/stream+json');
    
        res.write('[');
        for (let i = 1; i <= 1000; i++) {
            res.write(JSON.stringify(`data ${i}`));
            if (i < 1000) {
                res.write(",");
            }
            await sleep(1); // Simulates a delay
        }
        res.write(']');
        res.end();
    });
    
    const port = 3000;
    app.listen(port, () => {
        console.log(`Server running on http://localhost:${port}`);
    });
    
        2
  •  1
  •   user5211470    3 周前

    使用 netcat ,返回的数据的步调似乎是正确的,而且 chunk encoded .

    echo -ne 'GET /stream HTTP/1.1\n\n' | netcat localhost 8080
    

    输出示例:

    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: application/json
    Date: Mon, 06 May 2024 08:58:26 GMT
    Connection: keep-alive
    Keep-Alive: timeout=5
    Transfer-Encoding: chunked
    
    1
    [
    8
    "data 1"
    1
    ,
    8
    "data 2"
    1
    ,
    8
    "data 3"
    1
    ,
    8
    "data 4"