如何从 Google Cloud Functions 发送 gzipped json 响应?

How to send gzipped json response from Google Cloud Functions?

如果我使用 gzip 压缩进行响应,我在 Google 云功能之一中的 JSON 响应的大小最多可减少 70-80%。

如何从我的函数发送压缩的 json 响应(通过 http(s) 触发)?

这也意味着我可以通过 google 云平台节省大量网络费用,并为数据的移动消费者更快地加载数据。

我试过使用 zlib 本机模块,但没有成功...

if (req.get('Accept-Encoding') && req.get('Accept-Encoding').indexOf('gzip') > -1) {

    interpretation.gzip = true;

    const zlib = require('zlib');

    res.set('Content-Type', 'text/plain');
    res.set('Content-Encoding', 'gzip');

    zlib.gzip(JSON.stringify(interpretation), function (error, result) {
        if (error) throw error;
        res.status(200).send(result);
    })

} else {
    interpretation.gzip = false;
    res.status(200).send(interpretation);
}

在Postman中,响应的大小是一样的,content-type变了,但是没有在响应中设置Content-Encoding header...

您或许可以尝试使用 zlib 模块来处理压缩并为响应设置适当的编码:

exports.helloWorld = function helloWorld(req, res) {
  const zlib = require('zlib');

  // Obtain JSON stream from your source...

  res.status(200);

  res.set('Content-Type', 'text/plain');
  res.set('Content-Encoding', 'gzip');

  json.pipe(zlib.createGzip()).pipe(res);
};

当然需要先检查client是否接受gzip。此外,使用 zlib 编码可能会很昂贵,并且应该缓存结果。

查看 App Engine FAQ,特别是问题“我如何提供压缩内容?”的答案:

....To force gzipped content to be served, clients may supply 'gzip' as the value of both the Accept-Encoding and User-Agent request headers. Content will never be gzipped if no Accept-Encoding header is present...

此外,在 this group post 中有一个示例,说明如何使用 Accept-EncodingUser-Agent 的组合使用 Cloud Functions 发送请求:

curl -v "https://us-central1-<project>.cloudfunctions.net/test" -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" -H "Accept-Encoding: gzip"

Expressjs Production best practices: performance and reliability says below, which could be adapted for basic Node.js. They use the popular compression package available on NPM.

使用 gzip 压缩

Gzip 压缩可以大大减小响应主体的大小,从而提高网络应用程序的速度。在您的 Express 应用程序中使用压缩中间件进行 gzip 压缩。例如:

var compression = require('compression')
var express = require('express')
var app = express()
app.use(compression())