Flutter应用对接Odoo认证时的CORS跨域问题排查
Flutter对接Odoo认证的CORS问题解决方案
问题核心原因
浏览器会对跨域请求发起OPTIONS预检请求,而Postman/Python脚本不会触发这一机制,所以你的Odoo配置大概率没正确处理OPTIONS请求,或者存在配置错误导致CORS头未正确返回。
先修正2个明显错误
1. odoo.conf配置错误
你在odoo.conf中添加了Python路由代码,这完全不符合配置文件的规则,立即删除这部分内容,否则会导致Odoo启动异常或配置失效。
2. Flutter请求头冗余
Flutter代码中添加的Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers是服务器响应时才需要返回的头,客户端请求不需要发送,删除后保留必要头:
const headers = { 'Content-type': 'application/json', 'Accept': 'application/json', };
正确配置Odoo的CORS处理
方案1:自定义模块继承修改路由(推荐,不碰核心代码)
创建一个自定义Odoo模块,通过继承覆盖默认认证路由,直接处理OPTIONS预检请求:
- 在模块的
controllers/main.py中添加代码:
from odoo import http from odoo.http import request class CustomAuthController(http.Controller): # 覆盖默认认证路由,明确支持OPTIONS方法 @http.route('/web/session/authenticate', type='json', auth="none", cors="*", methods=['POST', 'OPTIONS']) def authenticate(self, db, login, password, base_location=None): # 直接处理OPTIONS预检请求 if request.httprequest.method == 'OPTIONS': headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Accept', 'Access-Control-Max-Age': '86400', # 缓存预检结果1天 } return request.make_response('', headers=headers) # 处理正常的POST认证请求 request.session.authenticate(db, login, password) return request.env['ir.http'].session_info()
- 安装该模块,重启Odoo服务。
方案2:全局处理CORS(修改核心代码,不推荐)
如果必须修改Odoo核心代码,替换odoo/http.py中的dispatch方法,直接处理所有OPTIONS请求:
def dispatch(self): # 优先处理OPTIONS预检请求 if request.httprequest.method == 'OPTIONS': headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, DELETE', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization', 'Access-Control-Max-Age': '86400', } return Response(status=200, headers=headers) response = super(HttpRequest, self).dispatch() # 给所有响应添加CORS头 response.headers['Access-Control-Allow-Origin'] = '*' response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS, PUT, DELETE' response.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization' return response
验证与排查
- 检查预检请求:用浏览器开发者工具查看OPTIONS请求的响应,确认包含
Access-Control-Allow-Origin: *且状态码为200。 - 清除缓存:浏览器可能缓存旧的CORS响应,用隐身模式测试或清除缓存。
- 确认路由生效:自定义模块的路由需确保参数(
type='json'、auth="none")与原路由一致,且模块已安装。
内容的提问来源于stack exchange,提问作者Hamza Khan
相关产品推荐
相关产品推荐

