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

Python3 Twisted反向代理重定向异常,请求技术协助

问题分析与解决

你的问题根源在于两点:

  1. 目标站点(YouTube/Yahoo)强制使用HTTPS,但你的代理默认连接80端口(HTTP),触发站点重定向时浏览器会错误拼接地址;
  2. Twisted原生ReverseProxyResource未正确处理重定向的Location头,导致跳转路径混乱。

修正后的代码

from twisted.internet import reactor
from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.web import proxy

class FixedReverseProxyResource(proxy.ReverseProxyResource):
    def getChild(self, path, request):
        # 正确拼接子资源路径,保留代理前缀
        return FixedReverseProxyResource(
            self.host, self.port, self.path + b'/' + path,
            self.secure, self.reactor
        )

    def render(self, request):
        # 传递正确的Host头,避免目标站点返回错误重定向
        request.requestHeaders.setRawHeaders(b'host', [self.host.encode('utf-8')])
        return super().render(request)

    def proxyFactory(self, *args, **kwargs):
        factory = super().proxyFactory(*args, **kwargs)
        # 重写重定向处理,修正Location头
        original_handle_end = factory.handleResponseEnd
        def handle_response_end():
            if factory.response_headers.hasHeader(b'location'):
                locations = factory.response_headers.getRawHeaders(b'location')
                corrected_locations = []
                target_host = self.host.encode('utf-8')
                proxy_prefix = b'/app1' if self.host == 'youtube.com' else b'/app2'
                local_proxy = b'http://127.0.0.1:8090' + proxy_prefix
                for loc in locations:
                    if loc.startswith(b'https://' + target_host):
                        # 替换目标域名为本地代理地址
                        path = loc[len(b'https://' + target_host):]
                        corrected_locations.append(local_proxy + path)
                    else:
                        corrected_locations.append(loc)
                factory.response_headers.setRawHeaders(b'location', corrected_locations)
            original_handle_end()
        factory.handleResponseEnd = handle_response_end
        return factory

# 连接目标站点的HTTPS端口,开启secure模式
site1 = FixedReverseProxyResource('youtube.com', 443, b'', secure=True)
site2 = FixedReverseProxyResource('yahoo.com', 443, b'', secure=True)

root = Resource()
root.putChild(b"app1", site1)
root.putChild(b"app2", site2)

reactor.listenTCP(8090, Site(root))
reactor.run()

关键修改说明

  • 切换到HTTPS端口:目标站点均强制HTTPS,因此代理需连接443端口并设置secure=True,避免初始HTTP请求触发错误重定向;
  • 修正重定向路径:自定义代理资源类,重写proxyFactory方法修改Location头,将目标站点的域名替换为本地代理的地址和前缀(如https://youtube.com/watch转为http://127.0.0.1:8090/app1/watch);
  • 传递正确Host头:确保请求发送到目标站点时,Host头为目标域名而非本地代理地址,避免站点拒绝请求或返回错误跳转。

额外提示

部分站点存在反代理机制,可能需要在render方法中添加模拟浏览器的请求头(如User-Agent),才能正常访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:14