零成本搭建私有扫码挪车服务:基于 Cloudflare Workers + Bark
停车被堵、打对方电话尴尬、挪车码还要收费——作为一个偶尔需要挪车、更多时候是被堵的车主,我决定自己动手,用完全免费的方式解决这个问题。
一、痛点:停车场的「死局」
相信每个开车的人都遇到过这种场景:
在商场地下车库转了三圈,终于找到一个车位,却发现自己的车被一辆车堵住了
在老旧小区加班到深夜,回家发现车被堵在消防通道里
对方车窗没有留任何联系方式,打 114 转接要等十几分钟
现有解决方案各有缺陷:
我想要的方案很简单:扫码 → 车主收到通知 → 确认/拒绝 → 文明沟通。而且必须免费、私有、不依赖任何付费服务。
于是,就有了这个项目。
二、解决方案:一图读懂扫码挪车
扫码挪车是一种「通知型」挪车解决方案,车主提前注册并生成专属二维码,放在车窗前。有需要挪车的人扫码后,车主立刻收到 iOS 推送通知,包含场景、地点、车主确认链接等信息,全程无需交换电话号码。
核心优势:
🚫 无需打电话:扫码即推送,文明又体面
💰 完全免费:基于 Cloudflare Workers 永久免费额度
🔒 隐私安全:Token 不暴露,车主可随时禁用
📍 位置感知:支持高德地图地理编码,显示详细地址
⏱️ 防骚扰机制:无位置提交需等待 30 秒,每天有次数上限
✅ 双向反馈:车主可确认或拒绝,扫码者实时得知状态
三、技术架构详解
┌──────────────────────────────────────────────────────┐
│ 用户手机 │
│ 扫码 → 填写表单 → 提交 → Cloudflare Workers API │
└────────────────────────┬─────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌────────────┐ ┌───────────┐ ┌─────────────┐
│ Cloudflare │ │ Workers │ │ 高德地图 │
│ Pages │ │ KV │ │ 地理编码 │
│ (前端页面) │ │ (存储) │ │ (可选) │
└────────────┘ └─────┬─────┘ └─────────────┘
│
▼
┌─────────────────┐
│ Bark API │
│ (iOS 推送通知) │
└─────────────────┘
3.1 Cloudflare Workers — 后端 API
Workers 是整个服务的核心,处理所有业务逻辑:
路由分发:
/api/register(注册)、/api/notify(通知)、/api/confirm(确认)、/api/reject(拒绝)、/api/status/*(状态查询)IP 地域检查:通过
CF-IPCountry请求头判断,仅允许 CN/HK/MO/TW 访问Bark 推送:调用 Bark 服务发送 iOS 推送
限流控制:每个车牌每天最多推送 20 次(可配置)
Workers 的优势在于:全球边缘部署、冷启动仅几百毫秒、每月 10 万次请求免费。
3.2 Workers KV — 数据存储
KV 是 Cloudflare 的键值存储服务,用于持久化以下数据:
KV 的优势是读取速度极快(全球一致性),适合这种读多写少的场景,且每天 100 万次读/写免费额度完全够用。
3.3 Cloudflare Pages — 前端页面
前端包含 4 个页面:
index.html— 扫码挪车主表单(选择场景、输入车牌、获取位置)register.html— 车主注册页面(绑定 Bark Key + 车牌,生成二维码)confirm.html— 车主确认/拒绝页面qr.html— 二维码展示与下载
前端通过 Fetch API 与 Workers 后端通信,所有页面纯静态,可部署在 Cloudflare Pages 或任何静态托管服务上。
3.4 Bark — iOS 推送服务
Bark 是一款开源的 iOS 推送工具,完全免费且支持自建服务器。车主只需安装 Bark App,复制自己的 Bark Key 填入注册表单即可。
推送消息包含: - 📍 场景标签(如「地下车库」「停车场出口」) - 🗺️ 详细地址(由高德地图地理编码转换) - 🔢 确认码(一次性安全码) - 🔗 确认链接(点击直接跳转到确认页面)
3.5 高德地图地理编码(可选)
通过 GPS 坐标调用高德地图 Web API,将经纬度转换为人类可读地址,如「广东省深圳市南山区科苑南路」。
此功能为可选配置,不填高德 Key 时仅显示坐标。
四、核心功能深度解析
4.1 车主注册(多车牌支持)
车主访问注册页面,填写: - 称呼(如「张先生」) - Bark Key(整个 Bark URL 地址) - 车牌号(支持多车牌,包含新能源车牌)
系统自动生成: - Token:16 位随机字符串,作为车主身份凭证 - Scan ID:8 位随机字符串,用于生成二维码
Token 由加密安全的随机数生成器(crypto.getRandomValues)生成,完全无法预测。
4.2 扫码通知流程
用户扫码后:
前端通过
scan_id查找对应车主的token用户选择场景(小区/商场/停车场出口等)、填写车牌号、情况说明
可选获取用户 GPS 位置(有位置立即推送,无位置等待 30 秒)
提交到
/api/notify服务端写入 KV,推送 Bark 通知
返回
pending_id,前端开始轮询通知状态
4.3 位置获取与地址解析
浏览器通过 navigator.geolocation.getCurrentPosition 获取用户 GPS 坐标。坐标会上报到 Workers,Workers 将坐标发送给高德地图地理编码 API,转换为详细地址。
地址会包含在 Bark 推送内容中,车主打开通知就能看到「广东省深圳市南山区科苑南路 xxx」这样的详细位置。
4.4 30 秒延迟防骚扰
这是本项目的一个重要设计决策:如果用户没有提供位置信息,通知会延迟 30 秒后才发送。
原因很简单:防止恶意骚扰。如果扫码就能立即推送,无位置限制的话,理论上可以批量扫描同一车牌进行骚扰。30 秒的等待时间足以让人三思而后行。
延迟期间,前端会显示环形倒计时动画。用户也可以选择填写位置来跳过等待。
4.5 车主确认/拒绝
车主点击推送中的链接(或扫码确认码)进入确认页面,可以:
✅ 确认挪车:服务端标记状态,同时向扫码者反向推送一条「车主已确认」通知,并附带扫码者位置链接
❌ 暂时不便:拒绝通知,扫码者收到拒绝提示
确认码(confirmed_key)是 24 位一次性随机字符串,核销后立即从 KV 中删除,防止重放攻击。
4.6 次数限制
每个 Token(车牌)每天最多推送 20 次。计数器以日期为键存储在 KV 中,第二天自动清零。超过上限后服务端返回 HTTP 429。
五、部署教程
第一步:创建 Cloudflare Worker
登录 Cloudflare Dashboard,点击 Create Worker
名称填写
scan-to-move-car(或你喜欢的名字),点击 Deploy点击 Edit code,删除全部代码
将
cloudflare/movecar.js的全部内容粘贴进去点击 Save and deploy
第二步:创建 KV Namespace
左侧菜单点击 KV
点击 Create a namespace
名称填写
SCAN_KV,点击 Create记下自动生成的 Namespace ID
第三步:绑定 KV 到 Worker
进入 Worker → Settings → Bindings
点击 Add binding,配置:
Variable name:
SCAN_KVKV namespace:选择刚才创建的
SCAN_KV
点击 Save
第四步:配置环境变量
在 Worker → Settings → Variables and Secrets 中添加:
第五步:部署前端到 Cloudflare Pages
进入 Cloudflare Pages
点击 Create a project → Direct upload
将
public/目录下的所有文件拖入上传区域项目名称随意填写,框架预设选 None
部署完成后,记下分配的
.pages.dev域名
第六步:修改前端 API 地址
在 public/ 目录下的所有 HTML 文件中,找到 API_BASE 配置,改为你的 Worker URL:
// 原始
const API_BASE = 'https://api.movecar.eggtata.top';
// 改为你的
const API_BASE = 'https://scan-to-move-car.your-name.workers.dev';
同时将 confirm.html 中的 CONFIRM_BASE_URL 指向你的 Pages 域名(不带路径),重新部署。
第七步:验证部署
访问:https://你的Pages域名/register.html
正常应显示车主注册页面,尝试注册后生成二维码,用另一台手机扫码测试完整流程。
六、隐私与安全
6.1 IP 地域限制
服务端通过 Cloudflare 的 CF-IPCountry 请求头判断访问者所在地区,默认仅允许:
CN(中国大陆)
HK(中国香港)
MO(中国澳门)
TW(台湾)
来自其他地区的请求直接返回 403,不执行任何业务逻辑。
6.2 Token 不暴露
扫码页面只暴露 scan_id(8 位随机字符串),无法反推出 token。真正的身份凭证 token(16 位随机字符串)只在注册成功后由服务端返回给车主本人。
扫码者只知道「发给谁」,不知道「车主是谁」,极大保护了车主隐私。
6.3 确认码一次性使用
确认码(confirmed_key)是 24 位加密随机字符串,在 confirm 或 reject 成功后立即从 KV 中删除。即使有人截获了确认链接,也无法重复使用。
6.4 次数限制
每个车牌每天最多 20 次推送,由 KV 原子计数器保证准确性。配合 30 秒延迟机制,有效防止批量骚扰。
七、开源信息
本项目已完全开源,欢迎 Star、Fork 和贡献代码!
GitHub 仓库: https://github.com/xJEYDAin/scan-to-move-car
如果你觉得这个项目对你有帮助,请给我一个 Star ⭐️!
八、写在最后
这个项目起源于我自己的真实需求。作为一个经常在老旧小区停车的人,我深刻理解找不到车主的痛苦,也理解打电话过去时双方的那种尴尬。
扫码挪车的设计哲学是:用技术消除摩擦,用规则保护隐私。30 秒延迟是为了防骚扰,但不会让正常用户等太久;次数限制是为了保护车主,但不会影响正常使用;Token 机制是为了隐私,但不会让用户记复杂的东西。
Cloudflare Workers + Bark 的组合让整个系统零成本运行,而且部署简单、维护量极小。如果你也有类似需求,不妨自己部署一个试试。
本文首发于 [ https://blog.eggtata.top ],采用 CC BY-NC-SA 4.0 协议开源。
评论区