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

Django类视图配置Cache-Control与ETag,实现城市ID动态缓存校验

解决方案

问题出在你的Cache-Control配置上:原来的max-age=3600会让浏览器在1小时内直接使用本地缓存,完全不向服务器发送请求,自然不会带上If-None-Match头,只有硬刷新才会强制触发校验。要实现每次请求都自动校验城市ID,需要调整缓存策略,同时完善ETag的生成逻辑:

1. 调整缓存控制头

把Cache-Control改为private, no-cache,这个指令的意思是:浏览器可以缓存响应,但每次使用缓存前必须向服务器校验ETag是否匹配,这样就能保证每次请求都会触发服务器的ETag校验逻辑。

2. 修正ETag生成逻辑

你的calculate_etag_value函数里的city_id没有明确来源,必须从当前请求中获取(比如请求参数、URL路径参数),否则无法正确生成对应城市的ETag。

修改后的完整代码

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

def calculate_etag_value(request):
    # 从请求中获取城市ID,示例为从query参数获取,根据你的实际场景调整
    city_id = request.query_params.get('city_id', '')
    # 给ETag加前缀避免冲突,同时符合HTTP规范用双引号包裹
    return f'"city-{city_id}"'

class MyAPIView(APIView):
    def get(self, request):
        current_etag = calculate_etag_value(request)
        # 处理客户端传来的ETag,去掉可能的双引号再对比
        client_etag = request.META.get('HTTP_IF_NONE_MATCH', '').strip('"')
        current_etag_clean = current_etag.strip('"')
        
        if client_etag == current_etag_clean:
            return Response(status=status.HTTP_304_NOT_MODIFIED)

        # 获取对应城市的最新数据
        city_id = request.query_params.get('city_id')
        if not city_id:
            return Response({"error": "城市ID不能为空"}, status=status.HTTP_400_BAD_REQUEST)
        
        my_data = retrieve_data(city_id)  # 传入城市ID获取对应数据
        
        headers = {
            'Cache-Control': 'private, no-cache',  # 关键修改:强制每次校验
            'ETag': current_etag,
        }
        response_data = {
            "message": "API info found",
            "data": my_data,
        }
        return Response(response_data, status=status.HTTP_200_OK, headers=headers)

关键说明

  • no-cache不是禁止缓存,而是强制缓存校验:浏览器会保存缓存,但每次请求都会把ETag发给服务器确认,匹配则返回304复用缓存,不匹配则返回新数据。
  • ETag格式建议用双引号包裹(符合HTTP标准),所以对比前要去掉客户端传来的引号。
  • 确保retrieve_data函数能根据城市ID返回对应的数据,保证ETag和数据的一一对应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:23:01