如何在Firebase Functions中原样接收GZIP编码的请求体而不自动解压
Firebase Function 接收gzip请求不自动解压的解决方案
Firebase HTTPS 函数默认会自动解析请求体,遇到Content-Encoding: gzip的请求时会自动解压内容到req.body,这个行为由内置的bodyParser中间件控制,你可以通过以下两种方案实现需求:
方案1:关闭默认bodyParser,手动读取原始请求体(推荐)
该方案可以兼容标准的Content-Encoding头规范,不需要客户端做特殊适配:
const functions = require('firebase-functions'); // 关闭内置的自动请求体解析 exports.store = functions.runWith({ https: { bodyParser: false } }).https.onRequest(async (req, res) => { // 校验请求编码头 if (req.headers['content-encoding'] !== 'gzip') { return res.status(415).send('gzip please'); } // 手动收集原始二进制gzip内容 const chunks = []; for await (const chunk of req) { chunks.push(chunk); } const rawGzipBody = Buffer.concat(chunks); // 可选:简单校验gzip格式合法性,避免无效内容 if (rawGzipBody.length < 2 || rawGzipBody[0] !== 0x1f || rawGzipBody[1] !== 0x8b) { return res.status(400).send('非法gzip内容'); } // 直接存储原始gzip内容即可,无需二次压缩 await store(rawGzipBody); return res.send('存储成功'); });
方案2:客户端使用自定义头标记gzip内容
如果不想修改默认bodyParser配置,可以让客户端不传递标准Content-Encoding: gzip头,改为传自定义头比如X-Content-Encoding: gzip,此时服务器不会自动解压请求体,你可以直接读取req.body的原始内容,同时校验自定义头即可,该方案实现更简单,但需要客户端配合调整请求头逻辑。
注意事项
- gzip是二进制格式,不要将
rawGzipBody转为UTF-8字符串存储,会导致内容损坏,建议直接存储Buffer或者转Base64字符串存储。 - 内置的gzip魔数校验逻辑足够应对绝大多数无效内容的场景,不需要额外实现复杂的识别规则。
内容的提问来源于stack exchange,提问作者Fudge Fudge
相关产品推荐
相关产品推荐

