FastAPI页面硬重载时接口被调用两次 favicon.ico来源问题排查
问题根因
favicon.ico是浏览器自动发起的默认请求:所有主流浏览器加载网页时,无需HTML手动引用,都会自动向站点根路径请求/favicon.ico,用于获取标签页、收藏夹展示的站点小图标。硬重载操作会清空本地缓存,强制重新发起包括favicon在内的所有资源请求。- 路由重复执行是通配路由匹配范围过大导致:你定义的
@router.get('/{inst_name}')属于根路径下的一级动态通配路由,没有路径前缀限制,所有根路径下的一级GET请求都会被它捕获。你主动访问业务路径触发第一次路由执行是正常逻辑,浏览器自动发起的/favicon.ico请求被该路由匹配后,会将favicon.ico作为inst_name参数传入,触发第二次执行,最终因为该值不是合法的标的代码触发断言报错。 - 此前运行无异常是因为普通刷新会复用缓存的favicon请求结果,不会重复发起请求,所以路由误匹配的问题一直没暴露,和你修改JavaScript代码没有关联。
修复方案
可根据自身需求任选一种方案修复:
- 方案一:调整业务路由路径,给业务接口增加明确前缀,比如将路由改为
@router.get('/chart/{inst_name}'),从路径层面把业务接口和根路径的静态资源请求隔离开,彻底避免通配路由误匹配。 - 方案二:如果必须保留根路径路由形式,在业务逻辑最前端增加favicon请求拦截,直接返回无内容响应即可,参考代码:
from fastapi.responses import Response @router.get('/{inst_name}') def chart(request: Request, inst_name: str): # 拦截浏览器自动发起的favicon请求 if inst_name == "favicon.ico": return Response(status_code=204) # 原有业务逻辑 lv = tse.LiveData(inst_name, 1) data = lv.get_data_for_charts('1min') return templates.TemplateResponse('chart.html', { 'request': request, 'title': inst_name, 'data': data })
- 方案三:在FastAPI中配置静态文件路由,将静态资源目录挂载到对应路径,目录中放置真实的
favicon.ico文件。静态路由的匹配优先级高于动态通配路由,favicon请求会被静态路由直接处理,不会进入业务逻辑。
内容的提问来源于stack exchange,提问作者Babak
相关产品推荐
相关产品推荐

