使用express-json-compress的Lambda函数在serverless下无响应问题
问题排查方案
1. 确认Serverless侧的响应头配置
- Lambda搭配API Gateway默认不会自动透传自定义的压缩响应头,你需要手动在API Gateway中开启二进制媒体类型支持,添加
application/json或者*/*到允许的二进制类型列表,否则gzip/deflate压缩后的响应会被API Gateway当成文本处理,导致乱码或者无响应。 - 检查
express-json-compress的默认配置,确认它设置的Content-Encoding头是否和你API Gateway允许的编码一致,部分serverless框架默认会覆盖响应头,你可以在调用res.compressJson之前手动加头确认:
res.setHeader('Content-Encoding', 'gzip'); res.setHeader('Content-Type', 'application/json');
2. 检查express在Serverless环境下的适配问题
- 你用的serverless express适配器(比如
serverless-http)是否支持流式响应/压缩响应,部分旧版本的serverless-http会自动解压响应内容再返回给Lambda,导致你压缩后的内容被二次处理失效,你可以升级到serverless-http最新版本,或者在初始化适配器的时候开启二进制支持:
const serverless = require('serverless-http'); const app = require('./app'); module.exports.handler = serverless(app, { binary: ['application/json'] });
3. 验证Lambda的执行权限和超时配置
- 首先确认Lambda是否有MongoDB的访问权限,比如VPC配置是否正确,安全组是否放行MongoDB的访问端口,本地能访问不代表Lambda部署后的VPC环境能访问数据库,可以先在代码里加日志排查数据库查询步骤是否正常执行:
app.post("/api/getDocAppoints", async (req, res) => { try { console.log('开始连接数据库'); const c = await client; console.log('数据库连接成功'); const db = await c.db("vytalconnect"); const collection = await db.collection('teamusers'); const data = await collection.find({ speciality: "Orthopedics" }).toArray() console.log('查询到数据条数:', data.length); var jsonString = JSON.stringify(data); console.log('序列化后字符串长度:', jsonString.length); res.compressJson(jsonString); } catch (err) { console.error('执行报错:', err); res.status(500).json({error: err.message}); } });
- 检查Lambda的超时时间配置,如果数据量太大,数据库查询+序列化+压缩的时间超过Lambda默认的3秒超时,也会直接返回无响应,建议先把超时时间调整到30秒测试。
4. 排查express-json-compress的兼容性问题
- 部分serverless环境下的res对象没有
end方法的默认适配,你可以不用这个第三方包,手动实现gzip压缩返回,避免兼容性问题:
const zlib = require('zlib'); const util = require('util'); const gzip = util.promisify(zlib.gzip); app.post("/api/getDocAppoints", async (req, res) => { const c = await client; const db = await c.db("vytalconnect"); const collection = await db.collection('teamusers'); const data = await collection.find({ speciality: "Orthopedics" }).toArray() const jsonString = JSON.stringify(data); const compressed = await gzip(jsonString); res.setHeader('Content-Encoding', 'gzip'); res.setHeader('Content-Type', 'application/json'); res.send(compressed); });
内容的提问来源于stack exchange,提问作者Onkar Sawant
相关产品推荐
相关产品推荐

