主题
Deep Link 参数 Schema & Router 分发最佳实践
适用场景:Electron(electron-builder / electron-forge)+ 自定义协议(Deep Link)
目标:让 Deep Link 像前端 Router 一样可维护、可扩展、可演进
Deep Link 参数 Schema & Router 分发最佳实践
一、为什么需要 Schema + Router
很多 Electron 项目在 Deep Link 上会走向下面这种状态:
text
myapp://open?type=login&id=123
myapp://open?foo=bar&x=y然后在主进程里写出👇这样的代码:
js
if (url.includes("login")) {
// ...
} else if (url.includes("order")) {
// ...
}问题会非常快地出现:
- ❌ 参数无规范,前后端理解不一致
- ❌ 无法做版本控制
- ❌ 难以扩展 / 回滚
- ❌ 安全边界模糊
解决方案:像设计 API 一样设计 Deep Link。
二、推荐的 Deep Link Schema 设计
1️⃣ 基础结构
text
myapp://action?version=1&payload=xxx我们强制拆成三层语义:
| 部分 | 含义 |
|---|---|
| scheme | 应用标识(myapp://) |
| action | 行为类型(login / open / navigate) |
| payload | JSON 负载(Base64 / URL Encode) |
2️⃣ Action 设计规范
text
myapp://login
myapp://navigate
myapp://open规则:
- action 必须是动词
- 一个 action = 一个业务入口
- 禁止复合动词(如 openLoginPage)
3️⃣ Payload 规范(核心)
推荐结构:
json
{
"version": 1,
"data": {
"path": "/order/detail",
"params": { "id": "123" }
}
}编码方式:
ts
const encoded = encodeURIComponent(btoa(JSON.stringify(payload)));最终 URL:
text
myapp://navigate?payload=eyJ2ZXJzaW9uIjoxLCJkYXRhIjp7fX0=三、统一的 DeepLink Router 设计
Router 职责
- 校验
- 分发
- 兜底
它不是业务逻辑,只是交通警察。
1️⃣ Router 接口定义
ts
export interface DeepLinkHandler {
action: string;
handle(payload: any): void;
}2️⃣ Router 实现
ts
export class DeepLinkRouter {
private handlers = new Map<string, DeepLinkHandler>();
register(handler: DeepLinkHandler) {
this.handlers.set(handler.action, handler);
}
dispatch(action: string, payload: any) {
const handler = this.handlers.get(action);
if (!handler) {
console.warn(`[DeepLink] Unknown action: ${action}`);
return;
}
handler.handle(payload);
}
}四、与 DeepLinkManager 集成
ts
function parseDeepLink(url: string) {
const u = new URL(url);
const action = u.hostname;
const payloadRaw = u.searchParams.get("payload");
let payload = null;
if (payloadRaw) {
payload = JSON.parse(atob(decodeURIComponent(payloadRaw)));
}
return { action, payload };
}ts
const router = new DeepLinkRouter();
router.register({
action: "navigate",
handle(payload) {
mainWindow.webContents.send("navigate", payload);
},
});
router.register({
action: "login",
handle() {
mainWindow.webContents.send("force-login");
},
});五、安全与演进策略
1️⃣ 白名单 Action
ts
const ALLOWED_ACTIONS = ["navigate", "login", "open"];2️⃣ 版本控制
ts
if (payload.version > CURRENT_VERSION) {
console.warn("Unsupported deep link version");
}3️⃣ 永远不要
- ❌ 直接执行系统命令
- ❌ 允许任意路径跳转
- ❌ 在主进程直接执行业务逻辑
六、前端如何配合(Vue / React)
ts
ipcRenderer.on("navigate", (_, payload) => {
router.push({
path: payload.data.path,
query: payload.data.params,
});
});七、总结
Deep Link 本质不是 URL,而是一个跨进程调用协议。
当你做到:
- Schema 稳定
- Router 可扩展
- Payload 可演进
你的 Electron 应用就已经具备:
- 企业级可维护性
- 长期演进能力
- 安全边界清晰