悲观更新需前后端协作实现,前端用JS调用/lock接口获取锁ID并置于请求头,后端校验锁有效性;HTML仅负责展示状态,不参与锁逻辑。

悲观更新不是 HTML 的事,是前端交互 + 后端协作的事
HTML 本身不支持“悲观更新”——它只是静态标记语言,没有状态、锁机制或事务概念。所谓“悲观更新”,本质是在用户提交修改前,先向后端申请锁定资源(如某条订单、某个配置项),成功锁定后才允许编辑;提交时再带着锁凭证完成写入,最后释放锁。整个流程必须由 JavaScript 驱动,并依赖后端提供 /lock、/unlock、/update?lock_id=xxx 这类接口支撑。
怎么用 JS 实现「点击编辑 → 尝试加锁 → 锁定失败就阻断」
核心是把“可编辑”状态和锁状态强绑定,不能只靠 UI 禁用按钮,得真正拦截提交逻辑:
- 点击“编辑”按钮时,立即发起
POST /api/v1/items/123/lock,携带user_id和可选的timeout=30 - 后端返回
{ locked: true, lock_id: "lk_abc456", expires_at: "2024-05-20T14:30:00Z" }才放开表单输入;否则弹提示“已被他人编辑”,并保持只读 - 表单提交前,必须在请求头带上
X-Lock-ID: lk_abc456,后端校验该锁有效且归属当前用户 - 提交成功后,主动调用
DELETE /api/v1/items/123/lock清理锁(不要依赖超时自动释放)
常见翻车点:锁没释放、锁被绕过、锁粒度错
这些不是写错 HTML 标签导致的,而是协作逻辑断裂:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 用户关闭页面或刷新,
unlock请求根本没发出去 → 后端必须设合理lock_timeout(建议 60–120 秒),且所有update接口要检查锁是否过期 - 用户禁用 JS,直接改
input的disabled属性再提交 → 后端必须做锁校验,绝不能只信前端传来的locked=true - 对整张用户表加锁,而不是对
user_id=123加锁 → 锁粒度要精确到业务实体 ID,避免误伤并发编辑其他记录 - 用 localStorage 存
lock_id,但多个标签页共用 → 导致一个页面解锁后,另一个页面还在用已失效的锁 ID 提交 → 应该每次操作都重新获取并校验
为什么不用 hidden input 存 lock_id?它不安全
<input type="hidden" name="lock_id" value="lk_abc456"> 看似方便,但会带来两个硬伤:
立即学习“前端免费学习笔记(深入)”;
- 用户可手动修改该值,伪造锁 ID 绕过后端校验 → 必须用请求头
X-Lock-ID或 Authorization Bearer 方式传递,服务端从 header 中读取 - 如果表单跨页面(比如分步编辑),
lock_id容易丢失或复用错误 → 更稳妥的方式是:每次提交都带当前会话有效的 lock_id,由后端判断是否续期或拒绝
锁的本质是服务端共识,不是前端状态同步。HTML 只负责展示“当前是否可编辑”,其余全交给 JS 和 API 对齐。


















