首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >什么是压缩away响应以避免6MB限制的好方法?

什么是压缩away响应以避免6MB限制的好方法?
EN

Stack Overflow用户
提问于 2020-05-26 15:11:46
回答 3查看 2.7K关注 0票数 4

我有Lambda,它执行几次对DynamoDB的调用,创建一个大的字符串化JSON对象作为响应,并通过API传递给客户端应用程序。当然,API有“内容编码启用”选项集,所有数据都以压缩的形式在互联网上传递。

问题是Lambda响应本身没有被压缩,并且达到了6MB的响应限制。是否有可能压缩Lambda响应,然后在客户端以某种自然的方式解压它?

我检查了node.js库,如JSZip和ADM Zip,并且惊讶地发现,尽管它们允许在内存中输出解压缩数据,但它们不允许字符串、缓冲区或smth之类的内存中输入,而只允许文件。Lambda已经有几个与处理文件相关的限制和惊喜,所以我想避免以下冗余的工作流:

environment

  • load
  1. 创建JSON对象
  2. ,将其保存为lambda中的一个时态文件,通过压缩库将其压缩并返回到API网关

有没有更自然的方法来处理这个问题?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-07-21 12:51:56

我遵循了下一个方法。后端:

代码语言:javascript
运行
复制
const { deflate, unzip } = require("zlib");
const { promisify } = require("util");

const asyncDeflate = promisify(deflate);

async zip(object) {
    return (await asyncDeflate(JSON.stringify(object))).toString("base64");`
}

前端:

代码语言:javascript
运行
复制
import * as pako from "pako";

export function unzip(base64str: string) {
  const strData = atob(base64str);

  // Convert binary string to character-number array
  const charData = strData.split("").map((x) => { return x.charCodeAt(0); });

  // Turn number array into byte-array
  const binData = new Uint8Array(charData);

  return JSON.parse(pako.inflate(binData, { to: "string" }));
}

因此,这与最近的答案相当相似。

票数 -1
EN

Stack Overflow用户

发布于 2021-07-02 19:41:42

虽然我同意使用分页或S3更适合于大量数据,但您可以压缩从Lambda函数返回的响应,以避免在需要时达到6MB的限制。

不幸的是,虽然API网关现在支持像gzip这样的内容编码,但我的理解是,在API压缩之前,Lambda函数的响应仍然需要低于6MB的限制。我不能百分之百地肯定这一点,所以如果我错了,请有人纠正我。

好消息是,node.js标准库现在已经通过zlib模块内置了对gzip的支持。我用这个来压缩刚刚超过6MB的响应,并将大小减少了大约78%。这样做的缺点是,我必须在我的角度客户端应用程序中手动解压缩数据(为此我使用了pako库)。

下面的内容对我很有用(打字稿4+ node.js 12):

代码语言:javascript
运行
复制
import { APIGatewayEvent, APIGatewayProxyResult } from 'aws-lambda';
import { gzip } from 'zlib';

export const handler = async (event: APIGatewayEvent): Promise<APIGatewayProxyResult> => {
  const response = { some: 'data' };

  const gzippedResponse = await gzipString(JSON.stringify(response));

  return {
    statusCode: 200,
    body: JSON.stringify({ data: gzippedResponse.toString('base64') }),
  };
};

const gzipString = async (input: string): Promise<Buffer> => {
  const buffer = Buffer.from(input);
  return new Promise((resolve, reject) => gzip(buffer, (err, data) => {
    if (err) {
      reject(err);
    }
    resolve(data);
  }));
};
票数 5
EN

Stack Overflow用户

发布于 2020-05-26 15:24:07

有多种方法可以通过稍微改变体系结构来处理这个问题:

  1. 只返回使用分页的响应的一个子集(如果响应包含可以溢出到多个页面的项列表,则效果最好)。
  2. Store部分或S3中的所有响应(如果响应是静态的,或者动态地创建),然后将对象的URL返回给客户端,以便随后检索。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62025368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档