如何在bottle.py中全局重写请求路径适配临时部署前缀?
解决Bottle应用在子路径部署下的URL前缀干扰问题
我之前刚好碰到过一模一样的部署场景,给你几个实用的解决方案:
方案1:代码层面修改WSGI环境变量
你说得没错,bottle.request的多数属性是只读的,但我们可以直接修改底层environ字典里的核心字段,让Bottle的路由解析彻底忽略前缀。
只需要在before_request钩子中修改PATH_INFO和REQUEST_URI这两个关键环境变量:
@bottle.hook('before_request') def strip_url_prefix(): target_prefix = '/secret_URL' current_path = bottle.request.environ.get('PATH_INFO', '') # 检查路径是否以目标前缀开头 if current_path.startswith(target_prefix): # 剥离前缀,更新PATH_INFO(Bottle路由解析完全依赖这个字段) bottle.request.environ['PATH_INFO'] = current_path[len(target_prefix):] # 同步更新REQUEST_URI,避免生成链接时带出多余前缀 bottle.request.environ['REQUEST_URI'] = bottle.request.environ['REQUEST_URI'][len(target_prefix):]
修改后,Bottle会自动把/secret_URL/A/B识别成/A/B来匹配路由,彻底解决前缀干扰问题。
方案2:用uWSGI内置参数(无需改动代码)
如果不想修改应用代码,uWSGI本身就支持处理子路径部署场景,启动时加上--mount和--manage-script-name参数即可:
uwsgi --http :1024 --mount /secret_URL=app.py --manage-script-name
这个参数会让uWSGI自动剥离/secret_URL前缀,把剩余路径传递给Bottle应用,全程不需要改一行代码,特别适合临时部署的场景。
处理模板中的链接(不用逐个修改href)
解决路由解析问题后,还要避免模板里的链接硬编码前缀。推荐用Bottle内置的url()函数生成链接,它会自动根据当前请求环境生成正确路径:
# 在bottle模板中这样使用 <a href="{{ url('somedef', A='foo', B='bar') }}">示例链接</a>
如果想统一设置基础URL,也可以在应用启动时配置:
app = bottle.default_app() app.config['base_url'] = '/secret_URL'
这样url()函数生成的所有链接都会自动带上前缀,客户端点击时直接指向正确路径,不用手动修改每个模板里的href。
补充说明:之前修改
bottle.request.url无效的原因是,url是Request类基于environ计算出的只读属性,直接修改它不会影响底层的路由解析逻辑,必须修改PATH_INFO这个核心环境变量才行。
内容的提问来源于stack exchange,提问作者handle
相关产品推荐
相关产品推荐

