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

React调用Flask接口时HTTPS被重定向为HTTP的问题排查

React + Flask(Heroku部署):HTTPS请求被转HTTP导致重定向循环/混合内容错误

问题概述

部署在Heroku上的React应用调用Flask后端/register接口时,出现两种异常情况:

  • 添加强制HTTPS的重定向代码后,触发GET https://example.com/register net::ERR_TOO_MANY_REDIRECTS无限重定向循环
  • 移除重定向代码后,出现混合内容错误:

    Mixed Content: The page at 'https://herokuapp.org/dashboard' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://example.com/register/'. This request has been blocked; the content must be served over HTTPS.

备注:代码中并未直接调用HTTP地址,HTTP请求来自重定向逻辑。

已尝试的代码

@app.before_request
def before_request():
    # avoid preflight redirects
    if request.method == 'OPTIONS':
        return jsonify({"status": "success"}), 200

    # if not preflight request and not HTTPS redirect to HTTPS
    HTTPS_ENDPOINTS = ['/register']
    if request.path in HTTPS_ENDPOINTS:
        if request.headers.get('X-Forwarded-Proto') == 'http':
            url = request.url.replace('http://', 'https://', 1)
            code = 301
            return redirect(url, code=code)

问题原因

  1. Heroku反向代理识别问题:Heroku的请求会先经过平台的反向代理,实际协议通过X-Forwarded-Proto头传递,但默认Flask不会信任这个头,导致即使实际是HTTPS请求,代码仍判断为HTTP,触发无限重定向。
  2. 混合内容根源:前端HTTPS页面发起的请求被错误重定向到HTTP地址,进而触发浏览器的混合内容拦截。

解决方案

1. 配置Flask信任Heroku反向代理

Flask需要明确知道自己运行在反向代理后方,才能正确读取代理传递的协议头。在app.py中添加以下配置:

from flask import Flask
import os
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)

# 生产环境下配置代理信任
if os.environ.get('HEROKU'):
    # 信任X-Forwarded-Proto(协议)和X-Forwarded-Host(主机)头,参数对应代理层数
    app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
    # 设置默认URL协议为HTTPS
    app.config['PREFERRED_URL_SCHEME'] = 'https'

说明:ProxyFix会让Flask的request.is_secure、request.url等属性基于实际的请求协议(HTTPS),而非代理转发后的HTTP。

2. 简化重定向逻辑(或移除)

配置ProxyFix后,无需手动读取X-Forwarded-Proto头,可改用Flask内置的request.is_secure判断是否需要重定向:

@app.before_request
def before_request():
    if request.method == 'OPTIONS':
        return jsonify({"status": "success"}), 200

    HTTPS_ENDPOINTS = ['/register']
    if request.path in HTTPS_ENDPOINTS and not request.is_secure:
        url = request.url.replace('http://', 'https://', 1)
        # 临时用302避免浏览器缓存,确认正常后再改回301
        return redirect(url, code=302)

如果配置ProxyFix后,所有请求已自动使用HTTPS,可直接移除这段重定向代码。

3. 验证前端API基础URL

确保React生产环境的API基础URL为HTTPS:

// React中配置API基础地址
const API_BASE_URL = process.env.NODE_ENV === 'production' 
    ? 'https://your-heroku-app-name.herokuapp.com' 
    : 'http://localhost:5000';

即使代码中没显式写HTTP,环境变量配置错误也可能导致生产环境请求HTTP地址。

4. 清除浏览器缓存

之前的301重定向可能被浏览器永久缓存,修复代码后需清除浏览器缓存(或使用隐私窗口测试),避免旧的重定向规则干扰。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:40:31