前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用SCF云函数输出gzip/deflate压缩过的数据,以及API网关的Bug

用SCF云函数输出gzip/deflate压缩过的数据,以及API网关的Bug

原创
作者头像
黄希彤
修改2022-08-22 14:46:09
8910
修改2022-08-22 14:46:09
举报
文章被收录于专栏:黄希彤的专栏黄希彤的专栏

最近用腾讯云SCF做了一个免费的高考志愿服务 填教授 需要输出大量的数据,这个时候直接吐数据给客户端就又慢又贵了,作为一个免费服务,还是需要努力降低流量成本的,因此尝试了一下SCF输出压缩数据。

代码语言:javascript
复制
'use strict';
const zlib = require("zlib");
exports.main_handler = async (event, context, callback) => {
    let res = new Array(1000).join("就是想测试一下SCF云函数输出做压缩好不好使\n");
    let encoding = event.headers['accept-encoding']||event.headers['Accept-Encoding'];
    console.log(encoding)
    if(/gzip/.test(encoding)){
        let data = zlib.gzipSync(res).toString("base64");
        return {
            isBase64Encoded:true,
            statusCode:200,
            headers:{
                "Content-Type":"text/json; charset=utf-8",
                'Access-Control-Allow-Origin:':'*',
                'Content-Encoding': 'gzip'
            },
            body:data
        }
    }else if(/deflate/.test(encoding)){
        let data = zlib.deflateSync(res).toString("base64");
        return {
            isBase64Encoded:true,
            statusCode:200,
            headers:{
                "Content-Type":"text/json; charset=utf-8",
                'Access-Control-Allow-Origin:':'*',
                'Content-Encoding': 'deflate'
            },
            body:data
        }
    }else{
        return {
            "isBase64Encoded": false,
            "statusCode": 200,
            "headers": {
                "Content-Type":"text/json; charset=utf-8",
                'Access-Control-Allow-Origin:':'*',
                },
            "body": res
        };
    }
};

需要做的主要就是把要返回的数据用zlib给压缩一下,然后用base64编码,最后通过集成响应方式吧编码数据输出给api网关。

看一下效果还不错:

压缩比、压缩程度等更多压缩选项可以参考 https://wiki.jikexueyuan.com/project/nodejs/zlib.html


刚看了一下API网关配置,在基础配置中不知道什么时候出现了“响应压缩”选项,还是默认选中的。这本来是一个很方便的好事,但是这次API网关的升级却带来了几个新的bug:

1 响应压缩无法关闭,唯一的关闭方式是自己声明content-encoding。而按照http协议,唯一允许声明content-encoding的情况是压缩,所以如果按照协议实现的话就还是无法关闭压缩,除非丢开协议不管了自己耍流氓声明个自定义的编码方式。

2 响应压缩声称对1k以内的内容不压缩,实际上对于非集成响应的SCF也没有兑现。

3 不管是否使用集成响应,api网关都不能正确吐出content-length头部了。就算SCF里面显式的声明了content-length也不行(唯一的例外是使用集成响应并且吐出的内容非常小的情况)。丢失了content-length信息会导致其他程序和系统出现不可预测的异常,比如COS通过api网关回源到SCF的情况下,如果获取不到content-length会直接保存下来一个0字节文件。

绕过这些bug的一个恶心的方式是scf总是压缩数据后输出,让api网关总是忽略相应压缩直接把压缩好的数据送出,此时cos会保存下来压缩过的文件,因此使用数据的程序需要自行解压数据。

官方推荐的一个也挺恶心的方式是自定义插件

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
API 网关
腾讯云 API 网关(API Gateway)是腾讯云推出的一种 API 托管服务,能提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档