web bluetooth 控制门锁必须使用 https(本地开发可用 localhost),需正确识别服务与特征值,写入前校验可写属性,权限为会话级且不持久,安卓端需规避省电限制。

门锁控制页必须用 HTTPS 才能调用 Web Bluetooth
浏览器里直接用 HTML 控制蓝牙门锁,navigator.bluetooth 是唯一可行路径,但它被强制要求运行在安全上下文(secure context)中。HTTP 协议下会直接报错 SecurityError: navigator.bluetooth is not available,连 inRange 都不会出现。
实操建议:
- 本地开发时用
localhost(Chrome/Firefox 允许其视为安全源,哪怕没 HTTPS) - 部署到真实设备时,必须配 TLS 证书——哪怕自签名,也要通过
https://访问 - Nginx 或 Caddy 配置里确认响应头含
Strict-Transport-Security,否则部分安卓 WebView 仍可能拒绝启用bluetooth
连接门锁设备前得先过滤出正确的 GATT Service 和 Characteristic
市面上多数智能门锁(如小米、云丁、Kaadas)使用标准 Bluetooth SIG 定义的 0x1816(Cycling Speed and Cadence)或私有 UUID(如 0000fee7-0000-1000-8000-00805f9b34fb),但真正下发开锁指令的 characteristic 往往是可写(writeWithoutResponse)+ 带通知(notify)的组合。
常见错误现象:能发现设备、能连接,但调用 characteristic.writeValue() 后无反应,或立刻断连。
实操建议:
- 用 nRF Connect App 先抓包确认门锁广播名、Service UUID、Control Characteristic UUID 和 expected value format(比如开锁指令可能是
Uint8Array.of(0x01, 0x00),不是字符串"open") - 在
device.gatt.connect()成功后,别直接getPrimaryService(),先device.gatt.getServices()全量列出,人工比对 UUID - 写入前务必检查
characteristic.properties.write为true,且characteristic.properties.writeWithoutResponse为true(多数门锁不支持带响应写入)
Web Bluetooth 的权限模型导致“一次授权、长期可用”不成立
Chrome 和 Edge 对 navigator.bluetooth.requestDevice() 的权限管理是 session 级别的:关掉标签页或刷新页面后,下次仍需用户手动点“允许”。它不像 geolocation 那样可持久化授权。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
这意味着你不能靠“记住上次设备”就自动重连——device.id 不稳定,device.name 可能为空,且没有后台保活机制。
实操建议:
- 页面加载后不要自动弹
requestDevice(),而是在用户点击“开锁”按钮时再触发,避免干扰体验 - 把选中的
device实例缓存在内存(非 localStorage),并在断连后优先尝试device.gatt.connect()而非重新 request - 监听
device.addEventListener('gattserverdisconnected', ...),而不是轮询device.gatt.connected,后者在断连瞬间可能还没更新
安卓 Chrome 上 Web Bluetooth 易受省电策略干扰
很多国产安卓机型(尤其华为、小米、OPPO)默认开启“应用省电优化”,会强制冻结后台网页的蓝牙扫描和连接能力,表现为:页面可见时正常,切到后台几秒后 requestDevice() 超时,或已连接设备突然 gattserverdisconnected。
这不是代码 bug,而是系统级限制。
实操建议:
- 在页面顶部加一行提示:
请在设置中将本页浏览器加入“电池优化白名单”,并给出跳转 intent(android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS) - 避免依赖长时后台连接——开锁动作本身应控制在 3 秒内完成(connect → write → confirm),完成后主动
device.gatt.disconnect() - 别用
setInterval模拟心跳;真要状态同步,改用服务端轮询 + WebSocket 推送门锁上报的状态
Web Bluetooth 控制门锁不是“写个 HTML 就能跑”,关键链路每一步都卡在浏览器策略、硬件协议、系统省电之间。最容易被忽略的是:你以为的“连接成功”,其实只是 GATT server 连上了,但门锁主控芯片是否已准备好接收指令,完全取决于它的固件实现——有些型号必须在 connect 后等待 800ms 才能写 characteristic,早了就静默失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










