如何在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
相关产品推荐
相关产品推荐

