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

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预检请求:

  1. 在模块的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()
  1. 安装该模块,重启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

验证与排查

  1. 检查预检请求:用浏览器开发者工具查看OPTIONS请求的响应,确认包含Access-Control-Allow-Origin: *且状态码为200。
  2. 清除缓存:浏览器可能缓存旧的CORS响应,用隐身模式测试或清除缓存。
  3. 确认路由生效:自定义模块的路由需确保参数(type='json'、auth="none")与原路由一致,且模块已安装。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:27:35