第三十六章 前端路由与控制器
篇别:第八篇 前端开发
本章学习目标
- 编写
type='http'与type='jsonrpc'的 Web Controller,理解auth、csrf、website的含义。 - 掌握 Odoo 19 中
json→jsonrpc路由类型变更的 迁移步骤与回归点。 - 理解 WebClient 中 URL(含 hash)与当前 action / 菜单 的 同步关系,能安全 分享深链。
- 能为 自定义 JSON API 编写 HttpCase 与 基本安全清单(鉴权、限流、输入校验)。
导读:控制器是「HTTP 边界」
Controller 是 Odoo 与 浏览器、移动端 App、Webhook 源站 之间的 HTTP 边界。这里最容易出现 CSRF 疏漏、鉴权过宽、JSON 解析错误未捕获 等问题。本章与 第三十章(安全)、第三十七章~三十八章(API) 强相关:同样一条 URL,可能是 网站页、JSON-RPC 或 自定义 REST,路由签名不同则 行为完全不同。
36.1 Web Controller
36.1.1 知识要点
http.Controller:类属性@http.route定义 路径、类型、认证、站点。type='http':返回 Response / QWeb / JSON(make_json_response);适用于 页面、文件下载、简单 JSON。auth:public(可匿名)、user(须登录后台用户)、none(极少用)等;网站路由 常website=True。csrf:表单与部分 HTTP POST 默认校验;csrf=False仅在有 替代防护 时使用(签名、API Key、内网)。request.env:与 ORM 一致;request.jsonrequest(若存在)仅jsonrpc路径典型可用——以版本为准。- 错误:捕获业务异常
UserError映射为 合适 HTTP 状态;勿 向客户端泄露 Python 栈(生产)。
36.1.2 案例
from odoo import http
from odoo.http import request
class LibraryController(http.Controller):
@http.route("/library/ping", type="http", auth="public", website=True, csrf=False)
def ping(self):
return request.make_json_response({"ok": True})
@http.route("/library/me", type="http", auth="user", methods=["GET"], website=True)
def me(self):
return request.make_json_response({"login": request.env.user.login})
36.1.3 截图占位

36.1.4 本节练习
- 实操:为
/library/me增加auth='user'的 未登录 访问测试(302 / 401 / 403 之一,以部署为准)。 - 简答:
website=True与website=False对 QWeb 布局与会话 的典型影响? - 判断:
auth='public'表示 不经过 Odoo 会话。( )
参考答案提示:3. 错;仍可有 匿名会话,取决于 网站中间件。
36.2 控制器类型变更(补充)
36.2.1 知识要点
- Odoo 19 起,旧式
type='json'路由应迁移为type='jsonrpc'(名称以 官方迁移说明 为准)。 - 语义:JSON-RPC 2.0 封装
jsonrpc、method、params、id;与 裸 REST JSON 不同。 - 客户端:前端
rpc/ormservice 依赖 正确路由类型;混用会导致 415 / 404 / 解析失败。 - 迁移:全仓库
grep "type='json'"→ 逐条替换 → 跑 smoke + 自定义集成测试。
36.2.2 案例
class LibraryApi(http.Controller):
@http.route("/library/jsonrpc/ping", type="jsonrpc", auth="user")
def jsonrpc_ping(self):
return {"pong": True}
36.2.3 截图占位

36.2.4 本节练习
- 实操:全局搜索
type='json',替换为jsonrpc后跑 登录与一条业务 RPC 烟测。 - 简答:jsonrpc 路由的 返回值 与 http + make_json_response 在 错误格式 上可能有何不同?
参考答案提示:2. JSON-RPC 封装错误对象;裸 JSON 常 自定义 status + body。
36.3 前端路由机制(新增)
36.3.1 知识要点
- WebClient 通过 action service、菜单、hash(或 history API,以版本为准)维持 「当前动作 ↔ URL」 同步。
- 分享链接:带
action、id、model等参数的 URL 可 直达某条记录;接收方须 有 权限 与 同一 db(dbfilter 环境尤需注意)。 - 多标签:不同标签 会话相同 时,互相覆盖 hash 可能造成 「以为丢了页面」——属 正常浏览器行为。
- 扩展:自定义 client action 若需 可分享状态,应将 关键参数 写入 action context / hash(设计时与 产品经理 对齐)。
36.3.2 案例
口述步骤:打开 销售订单列表 → 点开 某单表单 → 复制 地址栏 URL → 隐身窗口 登录同用户粘贴 → 核对 是否同一记录。
36.3.3 截图占位

36.3.4 本节练习
- 简答:分享带
id=的 URL 给同事需注意什么?(至少 权限、数据库、环境 三点中写两点。) - 判断:前端路由 完全由 Nginx rewrite 决定,与 Odoo WebClient 无关。( )
参考答案提示:2. 错。
本章综合练习
- 实现:JSON API(http + JSON) 返回 图书列表,支持
limit、简单domain查询参数,并写HttpCase(200 + JSON 结构)。 - 安全:
auth='public'接口的 rate limit 思路(Nginx、WAF、应用内计数 任选两层说明)。 - 综合:对比 第三十八章 REST 与 本章 jsonrpc:各写 一条 适用集成场景。
- 实操:为 jsonrpc 接口增加
UserError,观察 前端 notification 与 HTTP 状态(记录现象即可)。
本章对应白皮书目录:第三十六章 前端路由与控制器。 @http.route 装饰器参数、路径转换器与 http / jsonrpc 细节 见 第五十章《HTTP 控制器与 @http.route》。