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

如何在Bottle派生类中启用CORS以解决跨域请求阻塞问题?

在Bottle派生类中启用CORS的解决方案

我之前在做Bottle派生类项目时也踩过这个CORS的坑,试了好几种方法,总结出两个最适合派生类场景的解决方案,亲测有效:

方案一:在派生类初始化时注册全局After-Request钩子

这个方法的核心是在自定义的Bottle子类的__init__方法里,注册一个全局的after_request钩子,让所有响应自动带上CORS头,同时单独处理OPTIONS预检请求:

from bottle import Bottle, response, request

class MyCustomBottle(Bottle):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 注册CORS全局钩子
        self.hook('after_request')(self._add_cors_headers)
        # 单独处理OPTIONS预检请求(避免路由匹配失败)
        self.route('/<:re:.*>', method='OPTIONS')(self._handle_options)

    def _add_cors_headers(self):
        # 开发环境可临时用*,生产环境务必替换为具体前端域名
        response.headers['Access-Control-Allow-Origin'] = 'http://localhost:3000'
        response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
        response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With'
        # 如需携带Cookie/认证信息,开启下面这行,同时Allow-Origin不能用*
        response.headers['Access-Control-Allow-Credentials'] = 'true'

    def _handle_options(self):
        # 预检请求直接返回200即可
        return response

# 实例化自定义类
app = MyCustomBottle()

# 正常定义你的路由
@app.route('/api/hello', method='GET')
def hello():
    return {'msg': 'Hello from CORS-enabled API!'}

if __name__ == '__main__':
    app.run(host='localhost', port=8080)

为什么这个方案适合派生类?

因为钩子是在子类初始化时注册的,所有基于这个子类实例化的应用都会自动继承CORS配置,不用在每个路由上重复加装饰器,非常适合统一管理。


方案二:派生类中自定义CORS插件全局安装

Bottle的插件机制可以让你给所有路由自动应用逻辑,在派生类里安装自定义CORS插件,同样能实现全局CORS支持:

from bottle import Bottle, response, request

class MyCustomBottle(Bottle):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 全局安装CORS插件
        self.install(self._cors_plugin)

    def _cors_plugin(self, callback):
        def wrapper(*args, **kwargs):
            # 先处理OPTIONS预检请求
            if request.method == 'OPTIONS':
                response.headers['Access-Control-Allow-Origin'] = 'http://localhost:3000'
                response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS'
                response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With'
                response.headers['Access-Control-Allow-Credentials'] = 'true'
                return response
            # 正常请求添加CORS头
            response.headers['Access-Control-Allow-Origin'] = 'http://localhost:3000'
            response.headers['Access-Control-Allow-Credentials'] = 'true'
            return callback(*args, **kwargs)
        return wrapper

# 实例化应用
app = MyCustomBottle()

@app.route('/api/data', method='POST')
def receive_data():
    return {'status': 'success', 'data': request.json}

if __name__ == '__main__':
    app.run(host='localhost', port=8080)

这个方案的优势

插件机制更灵活,如果你需要在某些路由上跳过CORS,可以在路由装饰器里加skip=['_cors_plugin']参数,非常方便。


重要注意事项

  • 生产环境不要用*作为允许源:必须替换为你的前端实际域名(比如https://your-frontend.com),否则会有安全风险。
  • 携带凭证时的特殊要求:如果你的前端需要发送Cookie或者HTTP认证信息,必须同时设置Access-Control-Allow-Credentials: true和具体的Access-Control-Allow-Origin(不能用*)。
  • 务必处理OPTIONS请求:浏览器会在跨域的非简单请求(比如POST带JSON)前发送OPTIONS预检请求,服务器必须正常响应这个请求,否则浏览器会阻止后续请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:32:51