在0.0.0.0上运行Flask应用时出现404错误的原因排查
问题根源:Flask的
SERVER_NAME配置导致路由匹配失败 你遇到的404问题确实和你的Flask配置里的SERVER_NAME有关,和Blueprint或者Swagger本身没有直接关系。
为什么会出现这个问题?
看你的工厂函数代码,你设置了:
app.config['SERVER_NAME'] = settings.FLASK_SERVER_NAME
Flask的SERVER_NAME参数会强制要求所有请求的Host头必须和这个值完全匹配,否则会直接返回404。
- 当你在本地用
localhost:5000访问时,请求的Host头是localhost:5000,和你的SERVER_NAME(应该是localhost:5000或类似值)匹配,所以路由能正常命中。 - 当你改成
host=0.0.0.0允许外部访问时,外部请求的Host头是你的EC2实例公网IP(比如165.225.34.185:5000),这个值和你设置的SERVER_NAME不匹配,Flask就会认为这个路由不存在,返回404。
解决方案
根据你的使用场景,有两种可行的解决办法:
1. 移除SERVER_NAME配置(推荐,如果你不需要子域名路由)
如果你的应用不需要处理子域名或者依赖SERVER_NAME生成URL的场景,直接在create_app()里注释掉这行配置:
# app.config['SERVER_NAME'] = settings.FLASK_SERVER_NAME
修改后重新运行应用,外部访问http://<你的EC2公网IP>:5000/api就能正常返回Swagger页面了。
2. 修改SERVER_NAME为外部可访问的地址
如果你必须保留SERVER_NAME,把settings.FLASK_SERVER_NAME的值改成你的EC2实例公网IP加端口,比如:
# 在settings文件里设置 FLASK_SERVER_NAME = "165.225.34.185:5000"
或者运行应用时动态覆盖这个配置:
def main(): app.config['SERVER_NAME'] = '165.225.34.185:5000' app.run(debug=True, threaded=True, host='0.0.0.0')
这样外部请求的Host头就会和SERVER_NAME匹配,路由就能正常工作了。
验证测试
修改后重新启动应用:
python application.py
然后用外部机器或者EC2上用curl测试(如果用第一种方案移除SERVER_NAME的话,直接访问即可):
curl -X GET http://<你的EC2公网IP>:5000/api
应该就能正常返回Swagger页面了。
内容的提问来源于stack exchange,提问作者ddd
相关产品推荐
相关产品推荐

