You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Accept-Encoding头实现Flask缓存双格式响应的方案问询

解决方案:基于请求头区分Flask-Caching缓存条目

要实现同时缓存原生JSON和GZIP压缩版响应,核心是让Flask-Caching根据请求头的accept-encoding状态生成不同的缓存键,具体步骤如下:

1. 自定义缓存键生成函数

Flask-Caching默认的缓存键只包含路由和参数,我们需要扩展它,把请求是否需要gzip压缩的标识加入缓存键:

from flask import request
from flask_caching import Cache

cache = Cache(config={
    "CACHE_TYPE": "SimpleCache",  # 替换为你实际使用的缓存类型
    # 其他缓存配置...
})

def custom_cache_key():
    # 判断请求头是否包含gzip编码需求
    accepts_gzip = 'gzip' in request.headers.get('accept-encoding', '').lower()
    # 基于默认逻辑生成基础键,再拼接gzip标识
    base_key = cache._make_cache_key()
    return f"{base_key}:gzip={str(accepts_gzip).lower()}"

2. 实现响应压缩与缓存结合的逻辑

用装饰器把压缩逻辑和缓存绑定,确保两种格式的响应都被缓存:

import gzip
from flask import jsonify, make_response

def gzip_cache(timeout=300):
    def decorator(f):
        @cache.cached(timeout=timeout, key_prefix=custom_cache_key)
        def wrapped(*args, **kwargs):
            # 获取原始数据
            raw_data = f(*args, **kwargs)
            if not isinstance(raw_data, (dict, list)):
                return raw_data  # 非JSON响应直接返回
            
            json_str = jsonify(raw_data).get_data(as_text=True)
            accepts_gzip = 'gzip' in request.headers.get('accept-encoding', '').lower()
            
            if accepts_gzip:
                # 压缩并构建响应
                compressed_data = gzip.compress(json_str.encode('utf-8'))
                resp = make_response(compressed_data)
                resp.headers['Content-Encoding'] = 'gzip'
                resp.headers['Content-Type'] = 'application/json'
                resp.headers['Content-Length'] = len(compressed_data)
                return resp
            else:
                # 返回原生JSON
                return jsonify(raw_data)
        return wrapped
    return decorator

3. 在视图函数中使用

给需要缓存和压缩的视图加上自定义装饰器即可:

@app.route('/api/large-data')
@gzip_cache(timeout=3600)
def get_large_data():
    # 生成大体积JSON数据的逻辑(例如返回1.41MB的内容)
    large_payload = generate_large_data()
    return large_payload

关键说明

  • 自定义缓存键通过custom_cache_key函数,将gzip=True/False拼接在基础键后,不同请求头会生成完全独立的缓存条目,实现双缓存效果。
  • 压缩操作仅在缓存未命中时执行一次,后续直接返回缓存好的压缩/原生响应,正好能节省你提到的31ms压缩耗时。
  • 完全适配你使用的flask==2.2.2和Flask-Caching==2.0.2版本,无需额外依赖。

内容的提问来源于stack exchange,提问作者Fabio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 14:22:46