如何从节点 js 向浏览器发送分块 gzip 响应
How to send chunked gzip response to browser from node js
我正在尝试以特定间隔发送 spaces 以避免 heroku
超时(30 秒),但我想支持 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 works correctly in the browser and whole json response is received with spaces in the start. But for http://localhost:3000/gzip-chunked 浏览器似乎只接收到第一个 space 并且请求被终止。然而,来自 postman
的相同请求可以正常工作,并且可以在那里接收和解码整个响应。
浏览器是否期望整个响应是一个分成块的 gzip 主体而不是较小的 gzip 块?(浏览器不支持单独的 gzip 块感觉很奇怪:( )是否有任何其他选项我可以发回空 space 以保持连接?
编辑:
gzip中有没有解压时忽略的特殊字符?
这里有一个方法:
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');
});
我正在尝试以特定间隔发送 spaces 以避免 heroku
超时(30 秒),但我想支持 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 works correctly in the browser and whole json response is received with spaces in the start. But for http://localhost:3000/gzip-chunked 浏览器似乎只接收到第一个 space 并且请求被终止。然而,来自 postman
的相同请求可以正常工作,并且可以在那里接收和解码整个响应。
浏览器是否期望整个响应是一个分成块的 gzip 主体而不是较小的 gzip 块?(浏览器不支持单独的 gzip 块感觉很奇怪:( )是否有任何其他选项我可以发回空 space 以保持连接?
编辑: gzip中有没有解压时忽略的特殊字符?
这里有一个方法:
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');
});