如何在Heroku部署的Streamlit应用中强制跳转至HTTPS?
解决方案:强制Heroku上的Streamlit应用HTTP转HTTPS
Streamlit基于Tornado框架,无法直接复用Flask的Talisman工具,我们可以通过两种可靠方式实现强制HTTPS重定向,核心是利用Heroku反向代理传递的X-Forwarded-Proto头判断请求协议:
方法1:通过Tornado自定义Handler实现代码层面重定向
直接修改Streamlit应用逻辑,注入重定向处理:
- 创建
https_redirect.py文件,写入以下代码:
import streamlit as st from tornado.web import RequestHandler from tornado import web class HTTPSRedirectHandler(RequestHandler): def prepare(self): # 读取Heroku传递的原始请求协议头 proto = self.request.headers.get("X-Forwarded-Proto", "") if proto != "https": # 构造HTTPS地址并永久重定向 https_url = f"https://{self.request.host}{self.request.uri}" self.redirect(https_url, permanent=True) def setup_redirect(): # 获取Streamlit底层的Tornado应用实例 tornado_app = st.server.server.Server.get_current()._server._app # 给所有路由添加重定向Handler tornado_app.add_handlers(r".*", [(r".*", HTTPSRedirectHandler)]) # 初始化时执行重定向配置 setup_redirect()
- 在你的主Streamlit脚本开头导入该文件:
import https_redirect # 你的应用业务逻辑 st.title("HTTPS-Only Streamlit App")
方法2:使用Nginx Buildpack(无需修改应用代码)
通过Heroku的Nginx Buildpack处理反向代理和重定向,稳定性更强:
- 调整Buildpack顺序(Nginx需优先于Python):
heroku buildpacks:remove heroku/python heroku buildpacks:add heroku/nginx heroku buildpacks:add heroku/python
- 在项目根目录创建
nginx.conf.erb文件,添加重定向规则:
worker_processes <%= ENV['NGINX_WORKERS'] || 4 %>; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen <%= ENV['PORT'] %>; server_name my_webpage33.com; # 替换为你的自定义域名 # 检测协议并强制重定向 if ($http_x_forwarded_proto != 'https') { return 301 https://$host$request_uri; } # 代理请求到Streamlit服务 location / { proxy_pass http://127.0.0.1:8501; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } }
- 提交配置并重新部署:
git add nginx.conf.erb git commit -m "Add Nginx HTTPS redirect config" git push heroku main
关键注意点
- 必须依赖
X-Forwarded-Proto头判断协议,不能直接读取Tornado的request.protocol——因为应用运行在Heroku反向代理后,直接获取的是内部HTTP协议。 - 使用301永久重定向,让浏览器缓存重定向规则,提升后续访问效率。
内容的提问来源于stack exchange,提问作者Miguel Gonzalez
相关产品推荐
相关产品推荐

