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

FastAPI中间件更新Cookie后通知需两次刷新的问题排查与解决

问题原因分析与解决方案

原因解析

当前中间件的执行逻辑是先处理请求(包括渲染HTML模板),再查询通知数并设置Cookie,这就导致了两次刷新的问题:

  • 第一次刷新时,模板渲染依赖的是浏览器发送请求时携带的旧Cookie,此时新的通知Cookie还没被设置
  • Cookie是在响应阶段才写入浏览器的,只有第二次刷新时,浏览器才会把新Cookie带过来,模板才能读到最新的通知数

解决方案1:直接将通知数注入请求上下文(推荐)

跳过Cookie的往返依赖,在请求处理前就查询最新通知数,存入请求上下文,让模板直接读取这个实时值。

修改middleware.py:

async def get_user_notifications(request: Request, call_next):
    # 先查询最新通知数,再处理请求
    if await is_authenticated(request):
        user = await get_current_user(request)
        if user['is_notified']:
            notifications = await MessagesService.get_count(int(user['user_id']))
            request.state.notification_count = notifications['total'] if notifications else 0
        else:
            request.state.notification_count = 0
    else:
        request.state.notification_count = 0
    
    response = await call_next(request)
    return response

修改HTML模板:

{% if request.state.notification_count > 0 %}
    <small class="notification-badge">{{request.state.notification_count}}</small>
{% else %}
    <small class="notification-badge-empty">0</small>
{% endif %}

这样请求处理阶段就能拿到最新的通知数据,一次刷新即可显示结果。

解决方案2:保留Cookie同时同步模板数据(适用于需Cookie做其他逻辑的场景)

如果业务上需要保留user_notifications Cookie,可以在设置Cookie的同时,把实时通知数注入请求上下文,让模板直接使用上下文里的最新值,无需依赖请求携带的Cookie。

修改middleware.py:

async def get_user_notifications(request: Request, call_next):
    notification_count = 0
    if await is_authenticated(request):
        user = await get_current_user(request)
        if user['is_notified']:
            notifications = await MessagesService.get_count(int(user['user_id']))
            notification_count = notifications['total'] if notifications else 0
    
    # 存入请求上下文供模板实时使用
    request.state.notification_count = notification_count
    
    response = await call_next(request)
    
    # 同步设置/清除Cookie
    if notification_count > 0:
        response.set_cookie(
            key="user_notifications",
            value=str(notification_count),
            httponly=True,
        )
    else:
        response.delete_cookie("user_notifications")
    
    return response

修改HTML模板:

{% if request.state.notification_count > 0 %}
    <small class="notification-badge">{{request.state.notification_count}}</small>
{% else %}
    <small class="notification-badge-empty">0</small>
{% endif %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 10:41:17