如何从节点js向浏览器发送成组的gzip响应

问题描述 投票:0回答:1

我正在尝试以特定的间隔发送空格,以避免heroku超时(30s),但是我想支持gzip编码。所以我正在尝试类似如下的内容:

const express = require('express')
const zlib = require('zlib')

const app = express()
const gzipped_space = zlib.gzipSync(' ');

app.get('/json-chunked', function (req, res) {
  let interval = setInterval(() => {
    res.write(' ');
  }, 1000);

  setTimeout(() => {
    res.write('{"hello":"world"}');
    clearInterval(interval);
    res.end();
  }, 5500);
});

app.get('/gzip-chunked', function (req, res) {
  res.writeHead(200, {
    'Content-Encoding': 'gzip'      // setting the encoding to gzip
  });
  let interval = setInterval(() => {
    res.write(gzipped_space);
  }, 1000);

  setTimeout(() => {
    res.write(zlib.gzipSync('{"hello":"world"}'));
    clearInterval(interval);
    res.end();
  }, 5500);
});

app.listen(3000, () => {
  console.log('listening on 3000');
})

http://localhost:3000/json-chunked在浏览器中正常工作,并且接收到整个json响应,并在开始时带有空格。但是对于http://localhost:3000/gzip-chunked,浏览器似乎只接收第一个空格,并且请求被终止。但是,来自postman的相同请求可以正常工作,并且在那里接收并解码了整个响应。

浏览器是否希望整个响应是一个gzip主体,分成多个块,而不是较小的gzip压缩块?(感觉很奇怪,浏览器不支持单独的gzip压缩块:()我可以使用其他选项吗?发回空白处以保持连接状态?

编辑:gzip中是否有任何特殊字符在解压缩时会被忽略?

node.js express http browser gzip
1个回答
0
投票

这里是一种方法:

const zlib = require('zlib');
const express = require('express');

const app = express();

app.get('/gzip-chunked', function (req, res) {
  res.writeHead(200, {
    'Content-Encoding': 'gzip',      // setting the encoding to gzip
  });

  // Create a Gzip Transform Stream
  const gzip = zlib.createGzip();

  const interval = setInterval(() => {
    // Write a space character to the stream
    gzip.write(' ');

    // From Node.js docs: Calling .flush() on a compression stream will
    // make zlib return as much output as currently possible.
    gzip.flush();
  }, 1000);

  setTimeout(() => {
    gzip.write('{"hello":"world"}');
    clearInterval(interval);
    gzip.end();
  }, 5500);

  // Pipe the Gzip Transform Stream into the Response stream
  gzip.pipe(res);
});

app.listen(3000, () => {
  console.log('listening on 3000');
});
© www.soinside.com 2019 - 2024. All rights reserved.