Flask/Swagger经CloudFront HTTPS部署遇混合内容问题求助
Flask+EC2+CloudFront部署混合内容问题修复方案
问题背景
部署Flask应用到EC2,通过CloudFront分发HTTPS请求(转HTTP到EC2的Nginx),访问HTTPS URL时出现混合内容错误:
Fetch error Failed to fetch http://dev-api.mydomain.com/swagger.json Fetch error Possible mixed-content issue? The page was loaded over https:// but a http:// URL was specified. Check that you are not attempting to load mixed content.
核心原因
Flask运行在HTTP环境下(Nginx转发HTTP到Gunicorn),无法感知CloudFront传递的原始HTTPS请求协议,因此生成的Swagger文档链接使用了HTTP,导致页面(HTTPS加载)请求HTTP资源的混合内容问题。
修复步骤
1. 配置Flask识别转发的HTTPS协议
在Flask主应用文件(如app.py)中添加ProxyFix中间件,让Flask信任代理传递的协议头:
from flask import Flask from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # 适配CloudFront和Nginx的转发,信任X-Forwarded-Proto等头 app.wsgi_app = ProxyFix( app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1 ) # 可选:全局强制HTTPS URL生成 app.config['PREFERRED_URL_SCHEME'] = 'https'
重启Gunicorn服务生效。
2. 修正Nginx的转发头配置
当前Nginx中X-Forwarded-Proto用$scheme(值为http,因为Nginx监听80端口),需替换为CloudFront传递的原始协议头:
server { listen 80; server_name dev-api.mydomain.com; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 改用CloudFront传递的原始HTTPS协议头 proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_set_header CloudFront-Forwarded-Proto $http_cloudfront_forwarded_proto; } }
执行以下命令重启Nginx:
sudo systemctl restart nginx
3. 检查CloudFront分发配置
确保CloudFront行为设置满足:
- 在Origin Request Policy中,包含转发
X-Forwarded-Proto头到源站(EC2) - 为Swagger相关路径(如
/swagger.json、/swagger/)设置缓存策略为不缓存,避免旧的HTTP链接被缓存 - 确认CloudFront的SSL证书已正确绑定,分发状态为已部署
4. 验证Swagger文档配置(若使用Flask-RESTX/Flask-Swagger)
避免硬编码HTTP地址,让Swagger自动从请求头生成正确的HTTPS链接:
# 示例:Flask-RESTX配置 from flask_restx import Api # 不要硬编码base URL,依赖请求动态生成 api = Api(app, doc='/swagger/', prefix='/api')
验证
重启所有服务后,访问HTTPS URL,检查Swagger文档的请求地址是否已变为HTTPS,混合内容错误应消失。
内容的提问来源于stack exchange,提问作者juliano.net
相关产品推荐
相关产品推荐

