04 静态 UI 兜底与跨域(CORS) 本节摘要:这是第 3 章的收尾。请求来了,既不匹配路由、也不是引擎代理,怎么办?服务端还有个兜底——服务静态 UI。另外,跨域请求(CORS)怎么处理?本节讲清这两件「收尾」的事:静态 UI 兜底让服务端能独立托管前端,CORS 统一处理让跨域客户端能用。 一、静态 UI 兜底 考虑这个场景:一个请求进来,既不匹配任何业务路由,也不是引擎代理路径。默认会 404。但 OpenWork 服务端做了个聪明的兜底——尝试服务静态 UI 文件: 这个兜底让服务端能独立托管前端——前端构建产物(HTML/JS/CSS)可以被服务端当静态文件服务,用户访问服务端就能看到界面,不需要单独起前端服务器。
本节摘要:这是第 3 章的收尾。请求来了,既不匹配路由、也不是引擎代理,怎么办?服务端还有个兜底——服务静态 UI。另外,跨域请求(CORS)怎么处理?本节讲清这两件「收尾」的事:静态 UI 兜底让服务端能独立托管前端,CORS 统一处理让跨域客户端能用。
考虑这个场景:一个请求进来,既不匹配任何业务路由,也不是引擎代理路径。默认会 404。但 OpenWork 服务端做了个聪明的兜底——尝试服务静态 UI 文件:
请求进来 │ ▼ 路由匹配 │ ├─ 命中业务路由 ──► 执行 handler ├─ 引擎路径 ──► 代理 └─ 都没命中 │ ▼ 兜底:尝试服务静态 UI │ ├─ 是静态 UI 文件(如 /index.html) ──► 返回文件 └─ 不是 ──► 404
这个兜底让服务端能独立托管前端——前端构建产物(HTML/JS/CSS)可以被服务端当静态文件服务,用户访问服务端就能看到界面,不需要单独起前端服务器。
几个好处:
当然,开发时前端通常还是单独跑(热重载方便),生产部署时才用服务端托管静态 UI。这是「开发分离、部署合一」的常见模式。
💡 和 OpenCode 嵌入式 Web UI 的呼应:OpenCode 的单文件二进制内嵌 Web UI(OpenCode 教程第 12 章),思想类似——把前端打进后端,一体化分发。OpenWork 服务端托管静态 UI 是同一思路的不同实现。
现代 Web 应用经常遇到「跨域」——前端在 localhost:5173,服务端在 localhost:8787,前端调服务端就是跨域。浏览器默认会拦截跨域请求(同源策略),除非服务端通过 CORS(跨域资源共享) 显式允许。
OpenWork 服务端统一处理 CORS:
浏览器(前端)─OPTIONS─► 服务端:「我能跨域调吗?」 ◄─ 允许(来源/方法/头) 浏览器(前端)─POST─► 服务端:实际请求 ◄─ 响应(带 CORS 头)
服务端的 CORS 配置大致含:
| 配置 | 说明 |
|---|---|
| 允许的来源(origins) | 哪些前端域名可以跨域(如 localhost:5173) |
| 允许的方法 | GET/POST/... |
| 允许的头 | 请求可带的头 |
| 缓存时长(maxAge) | 预检结果缓存多久(避免重复预检) |
OpenWork 通常允许一组「已知前端来源」(如本地开发端口、生产域名)。配置可以是空的(不允许跨域,适合纯 API 场景),也可以列具体来源。
CORS 解决「浏览器让不让跨域」,鉴权(第 4 章)解决「服务端让不让访问」。两层独立:
跨域请求 │ ▼ 1. CORS:浏览器跨域检查(预检 + 响应头) │ ▼ 2. 鉴权:服务端权限检查(第 4 章) │ ▼ 都过 ──► 处理请求
CORS 过了不代表鉴权过——CORS 只是「浏览器层」的跨域许可,真正能不能访问还得看令牌 scope。
CORS 不是「麻烦」,是安全机制——它防止恶意网站偷偷调你已登录的服务端( CSRF 的一种防护)。所以:
*(允许所有来源)——那是关掉 CORS 保护。⚠️ 别设
*+ 带凭据:CORS 设*(任意来源)又允许带凭据(Cookies/Authorization),是危险组合——任意恶意网站都能借你的登录态调服务端。始终列具体来源。
读完第 3 章四节,你掌握了服务端这个「唯一中枢」的全貌:
| 节 | 讲了什么 |
|---|---|
| 01 路由引擎 | 正则编译式匹配,不用框架的极简中枢 |
| 02 能力声明 | 服务端自述能力,客户端据此适配 |
| 03 引擎反代 | 透明代理引擎,剥头注入凭据,viewer 只读 |
| 04 静态兜底 + CORS | 兜底服务 UI,跨域统一处理 |
核心认知:服务端用一个「正则路由 + 能力声明 + 引擎反代 + 静态兜底 + CORS」的极简组合,承担了整个产品中枢的所有职责。第 4 章我们钻进鉴权——四档鉴权与三级作用域。
*+带凭据,列具体来源。第 3 章结束。下一章讲鉴权与权限作用域——四档鉴权、三级 scope、viewer 强制只读。