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

Flask配置应用时出现404错误,请求排查原因

Flask加载配置后出现404错误的排查与解决

我遇到了一个奇怪的Flask问题:当移除app.py里加载配置的两行代码时,访问127.0.0.1:8000能正常返回"hey",但保留配置语句就出现404错误。先把我的项目情况贴出来:

项目目录结构

.
├── app.py
├── config/
│   ├── __init__.py
│   └── settings.py
└── instance/
    ├── __init__.py
    └── settings.py

代码详情

app.py

from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
from flask_mail import Mail
from flask_wtf.csrf import CsrfProtect

app = Flask(__name__)
debug_toolbar = DebugToolbarExtension()
mail = Mail()
csrf = CsrfProtect()

# 关键就是这两行:注释掉正常,保留就404
app.config.from_object('config.settings')
app.config.from_pyfile('settings.py', silent=True)

@app.route('/')
def hello_world():
    return "hey"

debug_toolbar.init_app(app)
mail.init_app(app)
csrf.init_app(app)

app.run(port=8000)

两个settings.py的代码

config/settings.py和instance/settings.py内容完全一致:

DEBUG = False
SERVER_NAME = 'localhost:8000'
SECRET_KEY = 'insecurekeyfordev'
# Flask-Mail.
MAIL_DEFAULT_SENDER = 'contact@local.host'
MAIL_SERVER = 'smtp.gmail.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USE_SSL = False
MAIL_USERNAME = 'you@gmail.com'
MAIL_PASSWORD = 'awesomepassword'
# Celery.
CELERY_BROKER_URL = 'redis://:devpassword@redis:6379/0'
CELERY_RESULT_BACKEND = 'redis://:devpassword@redis:6379/0'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_REDIS_MAX_CONNECTIONS = 5

问题原因分析

问题出在SERVER_NAME这个配置项上!

当你设置了SERVER_NAME = 'localhost:8000',Flask会启用严格的Host头匹配规则:

  1. 所有请求的Host必须严格等于这个值,否则Flask会认为请求的是其他站点,不会匹配你的路由。
  2. 你访问的是127.0.0.1:8000,此时请求的Host是127.0.0.1:8000,和配置里的localhost:8000不匹配,所以Flask找不到对应的路由,直接返回404。

而当你注释掉配置加载代码时,SERVER_NAME没有被设置,Flask会跳过这个严格匹配,所以127.0.0.1:8000的请求能正常命中根路由。


解决方案

有几种简单的解决方式,选适合你的就行:

  1. 修改访问地址:直接用localhost:8000代替127.0.0.1:8000访问,这样Host头和配置的SERVER_NAME完全匹配,就能正常返回内容。

  2. 调整配置:

    • 把SERVER_NAME改成'127.0.0.1:8000',和你实际访问的地址一致;
    • 或者直接删除SERVER_NAME配置项——如果你的项目不需要子域名路由、生成带域名的绝对URL这类功能,完全不需要设置这个参数,反而能避免这类匹配问题。
  3. 兼容多Host(进阶):如果确实需要保留SERVER_NAME同时兼容localhost和127.0.0.1,可以自定义Flask的路由匹配规则,或者设置APPLICATION_ROOT,不过这种情况比较少见,前面两种方案足够解决大部分场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:38:02