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

如何用Python Requests库正确返回HTTP响应(搭建Python反向代理)

解决子路径反向代理托管Flask应用的方案

首先,我猜你是想用middle.py作为反向代理层,把请求转发到helloflask.py的服务上对吧?而且不想占用80/443端口,那咱们可以用Flask配合Werkzeug的工具来实现,或者用更简洁的代理中间件,下面给你两种靠谱的实现方式:

方式一:手动实现Flask反向代理(灵活可控)

先给你的目标Flask应用(helloflask.py)配置子路径支持,不然内部路由会找不到正确的路径:

# helloflask.py
from flask import Flask
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)
# 告诉Flask它运行在/myapp子路径下
app.config['APPLICATION_ROOT'] = '/myapp'
# 配置ProxyFix,处理反向代理传递的请求头,避免路径识别错误
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1)

@app.route('/')
def hello():
    return "Hello from Flask app at /myapp!"

@app.route('/test')
def test():
    return "Test route accessible at /myapp/test!"

if __name__ == '__main__':
    # 让Flask仅监听本地指定端口,比如5000
    app.run(host='localhost', port=5000)

然后写middle.py作为对外的代理服务器,监听非80/443的端口(比如8080),把/myapp路径的请求转发到本地Flask服务:

# middle.py
from flask import Flask, request, Response
import requests

app = Flask(__name__)
# 目标Flask应用的本地地址
TARGET_APP_URL = 'http://localhost:5000'

@app.route('/myapp', defaults={'path': ''})
@app.route('/myapp/<path:path>')
def proxy_to_flask(path):
    # 拼接完整的目标请求URL
    target_url = f"{TARGET_APP_URL}/{path}"
    
    # 转发请求的所有信息:方法、数据、请求头(排除Host避免冲突)
    forwarded_req = requests.request(
        method=request.method,
        url=target_url,
        headers={k: v for k, v in request.headers.items() if k != 'Host'},
        data=request.get_data(),
        cookies=request.cookies,
        allow_redirects=False
    )
    
    # 处理响应头,去掉会引发问题的头字段
    excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
    response_headers = [(name, value) for name, value in forwarded_req.raw.headers.items() 
                       if name.lower() not in excluded_headers]
    
    # 生成响应,同时修正重定向地址(把目标地址替换成子路径)
    response = Response(forwarded_req.content, forwarded_req.status_code, response_headers)
    if 'Location' in forwarded_req.headers:
        old_location = forwarded_req.headers['Location']
        response.headers['Location'] = old_location.replace(TARGET_APP_URL, '/myapp')
    
    return response

if __name__ == '__main__':
    # 监听所有网卡的8080端口,对外提供服务
    app.run(host='0.0.0.0', port=8080)

运行步骤:

  1. 先启动目标Flask应用:python helloflask.py
  2. 再启动代理服务器:python middle.py
  3. 现在就可以通过http://myserver:8080/myapp访问你的Flask应用,http://myserver:8080/myapp/test访问测试路由

方式二:用Werkzeug ProxyMiddleware简化实现

如果你觉得手动写代理逻辑太麻烦,可以直接用Werkzeug的内置中间件,代码更简洁:

首先确保安装Werkzeug:pip install werkzeug

修改middle.py如下:

# middle.py
from werkzeug.middleware.proxy_fix import ProxyFix
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from flask import Flask

# 创建一个空的根应用,处理非/myapp路径的请求
root_app = Flask(__name__)
@root_app.route('/')
def root_page():
    return "This is the root server - visit /myapp to access your Flask app!"

# 导入你的目标Flask应用
from helloflask import app as flask_app

# 配置路由分发:把/myapp路径的请求转发给flask_app
application = DispatcherMiddleware(root_app, {
    '/myapp': flask_app
})

# 加上ProxyFix处理请求头,避免路径识别错误
application = ProxyFix(application, x_for=1, x_proto=1, x_host=1, x_prefix=1)

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    # 监听0.0.0.0:8080端口
    run_simple('0.0.0.0', 8080, application)

注意:helloflask.py的配置要和方式一保持一致(设置APPLICATION_ROOT和ProxyFix)。

关键注意事项

  • 必须给目标Flask应用设置APPLICATION_ROOT,不然它生成的内部URL(比如用url_for生成的链接)会不带子路径,导致跳转错误
  • 代理层一定要处理好Host和Location响应头,不然会出现重定向到错误地址的问题
  • 记得在服务器防火墙上开放代理层监听的端口(比如8080),不然外部无法访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 06:42:59